Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perform an action once nested fetch-es are complete?

The code below fetches an array from an API, then for each element of this array, retrieves further data.

fetch('https://reqres.in/api/users')
  .then(r => r.json()).then(r => {
    r.data.forEach(x => {
      fetch('https://reqres.in/api/users')
        .then(r => r.json()).then(r => {
          r.data.forEach(x => console.log(x.id))
        })
    })
  })

I need to perform some action on the data once it is fully retrieved. How to do that?

The problem is that this is a set of Promises which resolve asynchronously. Promise.all() could be used to gather all Promises and work from there - but their amount is not known upfront. In other words, I could use

a = fetch('https://reqres.in/api/users')
b = fetch('https://reqres.in/api/users')
Promise.all([a, b]).then(x => console.log('all resolved here'))

but what is passed to Promise.all() is not known when the script starts.

like image 629
WoJ Avatar asked Nov 20 '25 23:11

WoJ


1 Answers

...but what is passed to Promise.all() is not known when the script starts.

That's okay, you can use map instead of forEach and then wait on the result:

fetch('https://reqres.in/api/users')
  .then(r => r.json()).then(r =>
    Promise.all(r.data.map(x =>
      fetch('https://reqres.in/api/users') // (presumably there's some parameter here, you're not just repeating the same call...)
        .then(r => r.json())
        .then(r => {
          r.data.forEach(x => console.log(x.id))
        })
    ))
  );

The chain the above returns won't settle until all of the promises created in the map have resolved, or any of them has rejected.

like image 83
T.J. Crowder Avatar answered Nov 25 '25 00:11

T.J. Crowder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!