I need to create an asynchronous web app that uses vanilla JS , Web API(OpenWeather API) and and user data to dynamically update the UI. it's fast done, except one problem: the UI updates only at the second click of to generate Btn, I don't know where the bug could be? plz help me.
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);
}
};
CodePudding user response:
Add then directly to postData:
postData("/addData", {
name: data.name,
date: newDate,
temp: data.main.temp,
feelings: feelings
}).then(updateUI);
Or add return
getWeather(baseURL, newZip, apiKey)
.then(function (data) {
return postData("/addData", {
name: data.name,
date: newDate,
temp: data.main.temp,
feelings: feelings
});
})
.then(updateUI);
CodePudding user response:
The problems are in the performAction
function:
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());
}
Once getWeather
resolves, the callback passed to then
just calls postData
and returns undefined
causing the second then
's callback to execute early.
Just add a return
keyword before postData
and update the second then
block from then(updateUI())
to then(updateUI)
or 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());
}