Necesito crear una aplicación web asíncrona que use Vanilla JS, Web API (OpenWeather API) y datos de usuario para actualizar dinámicamente la interfaz de usuario. se hace rápido, excepto por un problema: la interfaz de usuario se actualiza solo con el segundo clic para generar Btn, no sé dónde podría estar el error. por favor ayudame.
Corte de pantalla del proyecto
const d = new Date(); const newDate = d.toDateString(); const baseURL = "http://api.openweathermap.org/data/2.5/weather?units=imperial&zip="; const apiKey = "&appid=b0c6dd1560b603095aed754d5d1756d0&units=imperial"; document.getElementById("generate").addEventListener("click", performAction); function performAction(e) { const feelings = document.getElementById("feelings").value; const newZip = document.getElementById("zip").value; getWeather(baseURL, newZip, apiKey) .then(function (data) { postData("/addData", { name: data.name, date: newDate, temp: data.main.temp, feelings: feelings }); }) .then(updateUI()); } const getWeather = async (baseURL, newZip, apiKey) => { const request = await fetch(baseURL + newZip + apiKey); try { const allData = await request.json(); if (allData.message) { alert(allData.message); } else { return allData; } } catch (error) { console.log("error", error); } }; const postData = async (url = "", data = {}) => { const res = await fetch(url, { method: "POST", credentials: "same-origin", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }); try { const newData = await res.json(); return newData; } catch (error) { console.log("error", error); } }; const updateUI = async () => { const req = await fetch("/all"); try { const allData = await req.json(); document.getElementById("name").innerHTML = allData.name; document.getElementById("date").innerHTML = allData.date; document.getElementById("temp").innerHTML = Math.round(allData.temp) + " degrees fahrenheit"; document.getElementById("content").innerHTML = "I am feeling "+allData.feelings; } catch (error) { console.log("error", error); } };Los problemas están en la función performAction :
function performAction(e) { const feelings = document.getElementById("feelings").value; const newZip = document.getElementById("zip").value; getWeather(baseURL, newZip, apiKey) .then(function (data) { postData("/addData", { name: data.name, date: newDate, temp: data.main.temp, feelings: feelings }); }) .then(updateUI()); } Una vez getWeather resuelve, la devolución de llamada pasa a then simplemente llama a postData y devuelve undefined , lo que hace que la segunda devolución de llamada then ejecute antes.
Simplemente agregue una palabra clave de return antes postData y actualice la segunda then bloquee desde then(updateUI()) hasta then(updateUI) o then(() => updateUI()) .
function performAction(e) { const feelings = document.getElementById("feelings").value; const newZip = document.getElementById("zip").value; getWeather(baseURL, newZip, apiKey) .then(function (data) { return postData("/addData", { name: data.name, date: newDate, temp: data.main.temp, feelings: feelings }); }) .then(() => updateUI()); }Agregue luego directamente a postData:
postData("/addData", { name: data.name, date: newDate, temp: data.main.temp, feelings: feelings }).then(updateUI);O agregar retorno
getWeather(baseURL, newZip, apiKey) .then(function (data) { return postData("/addData", { name: data.name, date: newDate, temp: data.main.temp, feelings: feelings }); }) .then(updateUI);