#javascript #api #fetch
#javascript #API #выборка
Вопрос:
Мне нужно выбрать город в Select, а затем вставить его в выборку, чтобы получить прогноз погоды для выбранного пользователем города, но я получил это сообщение до того, как у меня появилась возможность что-то выбрать: Uncaught ReferenceError: strUser не определен:
document.querySelector(".city-select").onchange = () => {
let strUser = document.querySelector(".city-select").value;
}
fetch(`'http://api.openweathermap.org/data/2.5/weather?q=${strUser}amp;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) 'amp;deg;';
})
.catch(function () {
});
Комментарии:
1. Поскольку вы использовали
let
strUser
переменную, область действия находится в пределах анонимной функции определенного вами обработчика событий. Кроме того, вы заключили URL-адрес вашегоfetch
вызова как в обратные, так и в одинарные кавычки, это кажется неправильным.
Ответ №1:
Ваша strUser
переменная ограничена обработчиком change
событий.
Кажется, вы хотите повторять fetch
всякий раз, когда это значение изменяется, поэтому я бы предложил поместить fetch
в функцию, которую вы можете вызывать в любое время, когда захотите обновить отображаемую информацию. Например:
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}amp;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) 'amp;deg;';
})
.catch(function () {
// Best to handle/report the error here
});
}
Примечание: вам не нужно повторно запрашивать DOM, чтобы найти элемент change
, с которым произошло событие, если вы используете традиционную функцию, а не функцию со стрелкой; вместо этого вы можете использовать this
внутри функции:
document.querySelector(".city-select").onchange = function() {
let strUser = this.value;
updateInfo(strUser);
};
Примечание 2: ваш код становится жертвой некоторой путаницы в fetch
API (я пишу об этом здесь). fetch
отклоняет свое обещание только при сетевых ошибках, а не при ошибках HTTP, поэтому ваш код может в конечном итоге вызвать json
, когда он получил ошибку 500 или 404 или аналогичную. Вы должны явно выполнить проверку успешности HTTP (именно поэтому я всегда включаю fetch
служебную функцию):
fetch(`'http://api.openweathermap.org/data/2.5/weather?q=${strUser}amp;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) 'amp;deg;';
})
.catch(function () {
// Best to handle/report the error here
});
Ответ №2:
Причина, по которой вы получаете ошибку, заключается в том, что let
ключевое слово имеет область действия блока и не может быть доступно в вашем fetch()
;
Кроме того, fetch()
является асинхронным.
Лучшим решением было бы обернуть ваш вызов fetch внутри функции и вызывать его только после strUser
того, как он доступен. Попробуйте это:
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}amp;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) 'amp;deg;';
})
.catch(function () {
});
}