Reputation: 69
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
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
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