Displaying Data from Javascript Fetch API - Question - javascript

I am new to working with APIs in javascript. I am looking to get input that a user puts into a box on a site (a city name) and fetch the API, to retrieve the temperature in that city. So far I have the following to fetch the API. But I am a bit lost on how to actually get that data and display it. How would I get the 'data'? I'm just not used to using APIs with Javascript and looking to learn more.
js file:
function hi() {
function temperature(input) {
const myKey = "Hidden_for_privacy";
const api = `https://api.openweathermap.org/data/2.5/weather?
q=${input}&lang=en&&appid=${myKey}&units=metric`;
fetch(api)
.then(function(response){
let data = response.json();
console.log(data);
return data;
})
Then I have this. searchUser is just representing the location the user types in:
const search = document.getElementById("searchUser");
const button = document.getElementById("submit");
button.addEventListener("click", () => {
const currentVal = search.value;
Relevant HTML:
<div class="container searchContainer">
<div class="search card card-body">
<h3>Get The Weather For a Location</h3>
<p class="lead">Enter Your Location</p>
<input type="text" id="searchUser" class="form-control"
placeholder="Location">
</div>
<br>
<div id="profile"></div>
</div>
<div class="container text-center mt-2">
<button class="btn btn-primary" id="submit">Submit</button>
</div>
<div id="content">
</div>

I think you have a few syntax errors going on before you can get into displaying data on the screen. I'd suggest concentrating on the JS implementation first to ensure you are successfully fetching data and loading it to the console. For instance, the closures in your JS might be causing problems. The hi function is creating a closure and then you are passing an argument of input into a function inside it but there is no local variables for it to grab.
Maybe try something like this to start and see what it logs:
function getTemperature() {
const myKey = "Hidden_for_privacy";
const api = `https://api.openweathermap.org/data/2.5/weather?
q=${input}&lang=en&&appid=${myKey}&units=metric`;
// .json returns a promise so you need to use .then to get the data from it synchronously
fetch(api)
.then((response) => response.json())
.then(data => console.log(data))
}

Related

How can I pass variable into function when the script text on prams

function domHTML(script, contact = {}, user = {}) {
console.log(contact.first_name);
console.log(user.name);
let dom = `
<div class="main py-3 w-100">
<div class="container">
<div class="content">
${script}
</div>
</div>
</div>`;
console.log(dom);
//return dom;}
let script = `Hey ${contact.first_name}, ${contact.first_name} this is ${user.name} giving you a quick call from the benefits office here in ${contact.state}. I’ll have you have the phone here sec but they have me giving you a quick call because of a form you filled out requesting more information about the life insurance programs through the state of ${contact.state}. They have me, the field underwriter, calling to verify the information, I have DOB as ${contact.birthday} is that correct? Perfect, so ${contact.first_name} like I said I’m just the field underwriter they have calling to let you know your request has been processed.
We’re doing everything virtually now due to covid. Takes about 10-15 min to get you the info. Grab a pen and paper for notes and will knock this out so you don’t get any more calls.`
I want to do every variable will be replaced with function arguments
You can turn your script into a function that accepts arguments and pass it to domHTML, that way script function can get the variables of contact and user passed to it.
function domHTML(fn ,contact = {}, user = {}) {
let theScript = fn(contact, user)
let dom = `
<div class="main py-3 w-100">
<div class="container">
<div class="content">
${theScript}
</div>
</div>
</div>`;
return dom;
}
function script(contact, user){
return `Hey ${contact.first_name}, ${contact.first_name} this is ${user.name} giving you a quick call from the benefits office here in ${contact.state}.
I’ll have you have the phone here sec but they have me giving you a quick call because of a form you filled out requesting more information about the life insurance programs through the state of ${contact.state}.
They have me, the field underwriter, calling to verify the information,
I have DOB as ${contact.birthday} is that correct? Perfect,
so ${contact.first_name} like I said I’m just the field underwriter they have calling to let you know your request has been processed.`
}
const dom = domHTML(script, contact, user)
console.log(dom)

Restcountries API - getting names of currencies dynamically into HTML through Javascript

I am new to Javascript and I've been learning how to import a country's attributes into an HTML element. Some of you might recognize this code, it's from a tutorial, which is now outdated. I've been searching around for an updated solution, but couldn't find any.
First I have the function to fetch the data:
const getCountryData = function (country) {
fetch(`https://restcountries.com/v3.1/name/${country}`)
.then(response => response.json())
.then(data => renderCountry(data[0]));
};
Then I call that function, supplying a country getCountryData('czechia') to infuse it into an element like this:
const renderCountry = function(data, className = '') {
const html = `
<article class="country ${className}">
<img class="country__img" src="${data.flags.svg}" />
<div class="country__data">
<h3 class="country__name">${data.name.common}</h3>
<h4 class="country__region">${data.region}</h4>
<p class="country__row">${(+data.population / 1000000).toFixed(1)} people</p>
<p class="country__row">${data.fifa}</p>
</div>
</article>
`
countriesContainer.insertAdjacentHTML
('beforeend', html);
countriesContainer.style.opacity = 1;
}
This works fine, but the issue is that at the end of the HTML, where I input {data.fifa} I want to have the name of the country's main currency instead. Unfortunately, the data is structured in a way, that in order to have the currency's name displayed, I first have to call it's short name, as shown below:
"currencies": {
"CZK": {
"name": "Czech koruna",
"symbol": "Kč"
}
},
If I call the {data.currencies} into the string, I'm just gonna get an empty object back. If I call it as {currencies.CZK.name}, it works, but the issue is that if I call Sweden, for example, it won't display anything, because then it'd need to be {currencies.SEK.name}. How do I get around this? How can I can call a currency's name without having to incorporate CZK, SEK, USD, EUR etc. into the variable?
Any help is appreciated.
You can transform that object into an array:
const currencyArray = Object.values(data.currencies)
console.log(currencyArray[0].name)
If the country has many currencies, just change the index from 0 to 1, 2, ...

Firebase Paginate

I made the code below referring to the pagination document of FIREBASE.
( https://firebase.google.com/docs/firestore/query-data/query-cursors#web-v8_3 )
I know that 'limit(3)' prints 3 documents, but I don't know how to use the 'next' and 'last' variables.
What I want to implement is to show three of my posts per page and move to the next page when the button is pressed.
Since I just started web development, everything is difficult. please help me
var first = db.collection('product').orderBy('date').limit(3);
var paginate = first.get().then((snapshot)=>{
snapshot.forEach((doc) => {
console.log(doc.id);
var summary = doc.data().content.slice(0,50);
var template = `<div class="product">
<div class="thumbnail" style="background-image: url('${doc.data().image}')"></div>
<div class="flex-grow-1 p-4">
<h5 class="title">${doc.data().title}</h5>
<p class="date">${doc.data().date.toDate()}</p>
<p class = "summary">${summary}</p>
</div>
</div>
<hr>`;
$('.container').append(template);
})
You can try this function:
let lastDocSnap = null
async function getNextPage(lastDoc) {
let ref = db.collection('product').orderBy('date')
// Check if there is previos snapshot available
if (lastDoc) ref = ref.startAfter(lastDoc)
const snapshot = await ref.limit(3).get()
// Set new last snapshot
lastDocSnapshot = snapshot.docs[snapshot.size - 1]
// return data
return snapshot.docs.map(d => d.data())
}
While calling this function, pass the lastDocSnap as a param:
getNextPage().then((docs) => {
docs.forEach((doc) => {
// doc itself is the data of document here
// Hence .data() is removed from original code
console.log(doc.id);
var summary = doc.content.slice(0,50);
var template = `<div class="product">
<div class="thumbnail" style="background-image: url('${doc.image}')"></div>
<div class="flex-grow-1 p-4">
<h5 class="title">${doc.title}</h5>
<p class="date">${doc.date.toDate()}</p>
<p class = "summary">${summary}</p>
</div>
</div>
<hr>`;
$('.container').append(template);
})
})
Call this function at page load (as lastDocSnap will be null, it'll fetch first 3 docs). Call the same function when user clicks 'next' but this time as we have lastDocSnap, the startAfter method will be added to the query. This essentially means the query will first order the document by date and then fetch 3 documents after the document you pass in startAfter

Cant show the icon by using API

Hope everyone is well.
This is my HTML code.
<div class="location">
<h1 class="location-timezone">Timezone</h1>
<img src="https://openweathermap.org/img/wn/04n.png" id ="image" alt=""class="icon" />
</div>
By using "openweathermap.org" API, I am trying to get the icon value. I have already got the temperature and other things. But when it comes to change the icon value, it doesnt change.
Below, I have attached my JavaScript code:
const api = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${long}&appid={API KEY}`
fetch(api)
.then(response =>{
return response.json();
})
.then(data => {
console.log(data);
const { icon} = data.weather[0];
iconButton.src=`http://openweathermap.org/img/wn/${icon}.png`
My question is what exactly I am doing wrong. Thanks in advance.
I tested the api, but everything seems to work fine.
It's probably the way you're changing the iconButton.src.
See if this sample helps:
var sample = {"coord":{"lon":145.77,"lat":-16.92},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"03n"}],"base":"stations","main":{"temp":300.15,"pressure":1007,"humidity":74,"temp_min":300.15,"temp_max":300.15},"visibility":10000,"wind":{"speed":3.6,"deg":160},"clouds":{"all":40},"dt":1485790200,"sys":{"type":1,"id":8166,"message":0.2064,"country":"AU","sunrise":1485720272,"sunset":1485766550},"id":2172797,"name":"Cairns","cod":200};
const { icon } = sample.weather[0]
document.querySelector('button').addEventListener('click', () => {
document.querySelector('.icon').src = `https://openweathermap.org/img/wn/${icon}.png`
})
<div class="location">
<h1 class="location-timezone">Timezone</h1>
<img src="https://openweathermap.org/img/wn/04n.png" id="image" alt="" class="icon" />
</div>
<button>Fetch new weather</button>

How to add counter in angular 6?

I have a function which grabs comments from the server, I would like to display total number of comments available in a server.
Here is the function in .ts file:
this.activeRouter.params.subscribe(params => {
// tslint:disable-next-line:prefer-const
let id = params['id'];
this.userService.getComments(id)
.pipe(
map(data => data.sort((a, b) => new Date(b.localTime).getTime() - new Date(a.localTime).getTime()))
)
.subscribe(data => this.comments = data);
});
Here is the get function in service
getComments (id: number) {
return this.http.get<Comment[]>(this.commentsUrl);
}
Here is the html for displaying comments
<div class="comments-description" *ngFor="let comment of comments">
<span class="comments_count">(353)</span>
<div class="comments-photo">
<img src="https://randomuser.me/api/portraits/men/84.jpg" alt="">
</div>
<div class="comments_wrapper">
<div class="comments_details">
<h1>{{comment.author}}</h1>
<span class="days">1d</span>
</div>
<div class="comments_text">
<p>{{comment.description}} </p>
</div>
</div>
</div>
why not simply use the length
<span class="comments_count">{{comments.length}}</span>
If you get all the comments in the response then you can use comments.length
<span class="comments_count">{{comments.length}}</span>
But the best practice is to get it from the API side. Add one more field in your API response for comment count.
Solution:
While getting comments data from server , You have to return total number of comments along with the new data.
Once you call service you can add data in one array.
and set total count in one variable.
Note:
You have to read count from sever and return result in same API or service
Update your API and get comments count using API and show your comment count.
Such counter must be on the server side.
For example, post has 10000 comments.
1 request will not fetch them all, only a portion (page).
And it's not good to get them all only to find out a count.
So the response should contain a 'count' field.

Categories

Resources