react developer
react developer

Reputation: 69

get data from array of objects containg promises

In my react app I have some user ids and need to fetch their emails and names from different endpoints so what i do is:

const promises = ids.map(
   id => (  {email: axios.get(`blabla/${id}/email`), name: axios.get(`blabla/${id}/name`)}  )
);

and it gets me back:

[
{email: Promise, name: Promise},{email: Promise, name: Promise},{email: Promise, name: Promise},...
]

Now to get the data what i do is:

  const results = [];
  promises.map(({ email, name}) =>
      Promise.all([email, name]).then((result) => {
        results.push({
          email: result[0].data,
          name: result[1].data,
        });
      })
    );

but i have a feeling that it may not be a good way to it, i mean it works now but i don't want to get into any issues later !! haha, for instance, a race between promises, or for instance, a user email set for another user. I don't know if they are even possible to happen but I need to check with you experts that if you confirm this way or do you suggest something else.

Upvotes: 2

Views: 84

Answers (2)

Siraj Alam
Siraj Alam

Reputation: 10025

I'd be doing it like this.

const promises = ids.map(
   id => (  [axios.get(`blabla/${id}/email`), axios.get(`blabla/${id}/name`)]  )
);
Promise.all(promises.map(Promise.all).then(
    ([email, name]) => {
        console.log(email, name)
    }
)).then(values => {
    console.log(values);
});

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074048

It's fine other than that you're not using the array map creates. Any time you're not using map's return value, use a loop (or forEach) instead. Also, any time you're writing to an array you're closing over from asynchronous operation results, it sets you up to accidentally use that array before it's populated

In this case, though, I'd use the array map gives back:

Promise.all(
    promises.map(({ email, name}) =>
        Promise.all([email, name])
        .then(([email, name]) => ({email, name}))
    )
).then(results => {
    // ...use results here, it's an array of {email, name} objects
})
.catch(error => {
    // ...handle error here, at least one operation failed...
});

Upvotes: 1

Related Questions