Chained fetches dependent on each other


Chained fetches dependent on each other



Take the following scenario:



I need to show in a table a list with all countries and the population of each country. All data can be queried from here: api.population.io.



Thare are 2 api calls that can help me achieve what i want:



As you can see i need to make 2 api calls since the second call is dependant of the name of the country made by the first call. I managed to make it work with the initial api call using fetch by using this code:


fetch('http://api.population.io:80/1.0/countries')
.then(results => {
return results.json();
}).then(data => {
//data.countries
})



This just returns me a list with all the countries.



Now i need to loop through data.countries and make a new api call for each country without breaking the whole process. I tried throwing another fetch call where data.countries is available while looping over data.countries but as you can imagine this breaks up the whole process, what i think happens is that the loop doesn't wait for the fetch call to complete thus messing up the query process.



I'm pretty new to this and i've tried googling it but i'm not sure what i can use to achieve what i need. Any help would be truly appreciated. I've been dealing with this problem the whole day





Side note: That fetch code is missing a check to see if the fetch failed; see my blog post about it.
– T.J. Crowder
Jun 30 at 18:47


fetch


fetch





See my answer here to the question How do I return the response from an asynchronous call?, which describes running a bunch of promise-enabled operatinos either in series (one after another) or in parallel (all at once).
– T.J. Crowder
Jun 30 at 18:49





Yes i know about the missing fail check, i'm just playing with it right now but i'll definitely add the missing code. Much appreciated for the tip.
– Adrian Savulescu
Jun 30 at 19:04




2 Answers
2



You could fire all the separate population requests at once and use the result when all of them have finished, with the help of Promise.all:


Promise.all


fetch("http://api.population.io:80/1.0/countries")
.then(results => {
return results.json();
})
.then(data => {
const populationPromises = data.countries.map(country => {
return fetch(
`http://api.population.io:80/1.0/population/${country}/today-and-tomorrow/`
).then(results => results.json());
});

return Promise.all(populationPromises);
})
.then(populations => {
console.log(populations);
})
.catch(error => {
console.error(error);
});





I see, that's interesting, i didn't know you can process data like that, i'll definitely try your approach. Thank you so much for the assistance
– Adrian Savulescu
Jun 30 at 19:04





@AdrianSavulescu You're welcome. It takes a while to get a grip of everything you can do with promises. Welcome to stackoverflow!
– Tholle
Jun 30 at 19:06



The approach with async/await makes the code more coherent and readable:


async/await


function getCountries() {
return fetch('http://api.population.io/1.0/countries/?format=json').then(s => s.json())
}

function getPopulation(country) {
return fetch(encodeURI(`http://api.population.io:80/1.0/population/${country}/today-and-tomorrow/?format=json`)).then(s => s.json())
}

(async () => {

try {

const { countries } = await getCountries();
const populations = await Promise.all(countries.map(getPopulation));

console.log(populations);

} catch(err) {
console.log(err);
}

})();






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

List of Kim Possible characters

Audio Livestreaming with Python & Flask

NSwag: Generate C# Client from multiple Versions of an API