I am trying to combine two fetch requests in one call so I can get all the data in the same array.
I have tried the Promise.all method but I don't know if it is the right way to do it.
getWeather = async (e) => {
e.preventDefault();
const city = e.target.elements.city.value;
//const api_call = await
const promises = await Promise.all([
fetch(`http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&APPID=${API_KEY}`),
fetch(`http://api.openweathermap.org/data/2.5/forecast?q=${city}&units=metric&APPID=${API_KEY}`)
])
const data = promises.then((results) =>
Promise.all(results.map(r => r.text())))
.then(console.log)
The code actually works and I'm getting data back but I can't understand the json response.
(2) ["{"coord":{"lon":-5.93,"lat":54.6},"weather":[{"id"…7086601},"id":2655984,"name":"Belfast","cod":200}", "{"cod":"200","message":0.0077,"cnt":40,"list":[{"d…on":-5.9301},"country":"GB","population":274770}}"]
How should I set the state? My state was set like this, with only one call.
if (city) {
this.setState({
temperature: data[0].main.temp,
city: data[0].name,
Is there a better way to do it?
I'd do:
getWeather = async (e) => {
e.preventDefault();
const fetchText = url => fetch(url).then(r => r.json()); // 1
const /*2*/[weather, forecast] = /*3*/ await Promise.all([
fetchText(`.../weather`),
fetchText(`.../forecast`)
]);
this.setState({ temperature: weather.temp, /*...*/ });
}
1: By using a small helper, you don't have to call Promise.all
twice. With this both requests are done in parallel (and you should use .json()
as you want to parse it as JSON).
2: Through array destructuring you can easily get back the promises results.
3: Through await
ing you get the actual benefit from async
functions: You don't need nested .then
chains
You can write in following way which is cleaner approach and will have your data categorised
const success = res => res.ok ? res.json() : Promise.resolve({});
const weather = fetch(`http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&APPID=${API_KEY}`)
.then(success);
const forecast = fetch(`http://api.openweathermap.org/data/2.5/forecast?q=${city}&units=metric&APPID=${API_KEY}`)
.then(success);
return Promise.all([weather, forecast])
.then(([weatherData, forecastData]) => {
const weatherRes = weatherData;
const ForecastRes = forecastData; // you can combine it or use it separately
})
.catch(err => console.error(err));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With