Reputation: 25
I need to choose the city in Select and then insert it to the fetch to get weather forecast of the user selected city, but I got this message before I got a chance to choose something:
Uncaught ReferenceError: strUser is not defined:
document.querySelector(".city-select").onchange = () => {
let strUser = document.querySelector(".city-select").value;
}
fetch(`'http://api.openweathermap.org/data/2.5/weather?q=${strUser}&appid=f3ab273b1163fcf008d6dce02f9e86e'`)
.then(function (resp) { return resp.json() })
.then(function (data) {
document.querySelector('.package-name').textContent = data.name;
document.querySelector('.temp').innerHTML = Math.round(data.main.temp - 273) + '°';
})
.catch(function () {
});
Upvotes: 0
Views: 985
Reputation: 8118
Why you are getting the error is because let
keyword has block scope and cannot be accessed within your fetch()
;
Also, fetch()
is asynchronous.
Best solution would be to wrap your fetch call inside a function and only once the strUser
is available call it. Try this:
document.querySelector(".city-select").onchange = () => {
let strUser = document.querySelector(".city-select").value;
getDetails(strUser);
}
function getDetails(strUser){
fetch(`'http://api.openweathermap.org/data/2.5/weather?q=${strUser}&appid=f3ab273b1163fcf008d6dce02f9e86e'`)
.then(function (resp) { return resp.json() })
.then(function (data) {
document.querySelector('.package-name').textContent = data.name;
document.querySelector('.temp').innerHTML = Math.round(data.main.temp - 273) + '°';
})
.catch(function () {
});
}
Upvotes: 1
Reputation: 1075337
Your strUser
variable is scoped to the change
event handler.
You seem to want to repeat the fetch
whenever that value changes, so I'd suggest putting the fetch
in a function you can then call any time you want to update the information it shows. For instance:
document.querySelector(".city-select").onchange = () => {
let strUser = document.querySelector(".city-select").value;
updateInfo(strUser);
};
function updateInfo(strUser) {
fetch(`'http://api.openweathermap.org/data/2.5/weather?q=${strUser}&appid=f3ab273b1163fcf008d6d3ce02f9e86e'`)
.then(function (resp) { return resp.json() })
.then(function (data) {
document.querySelector('.package-name').textContent = data.name;
document.querySelector('.temp').innerHTML = Math.round(data.main.temp - 273) + '°';
})
.catch(function () {
// Best to handle/report the error here
});
}
Side note: You don't need to re-query the DOM to find the element the change
happened on if you use a traditional function rather than an arrow function; you can use this
within the function instead:
document.querySelector(".city-select").onchange = function() {
let strUser = this.value;
updateInfo(strUser);
};
Side note 2: Your code is falling prey to a bit of a footgun in the fetch
API (I write about it here). fetch
only rejects its promise on network errors, not HTTP errors, so your code may end up calling json
when it's received a 500 or 404 error or similar. You have to do the check for HTTP success explicitly (which is why I always wrap fetch
in a utility function):
fetch(`'http://api.openweathermap.org/data/2.5/weather?q=${strUser}&appid=f3ab273b1163fcf008d6d3ce02f9e86e'`)
.then(function (resp) {
if (!resp.ok) { // ***
throw new Error("HTTP error " + resp.status); // ***
} // ***
return resp.json();
})
.then(function (data) {
document.querySelector('.package-name').textContent = data.name;
document.querySelector('.temp').innerHTML = Math.round(data.main.temp - 273) + '°';
})
.catch(function () {
// Best to handle/report the error here
});
Upvotes: 2