Reputation: 1272
I've looked at several questions on using async/await with a forEach loop but nothing seems to cover my user case... How can I get the code below to work? Right now I'm getting the following error:
await is a reserved word
Here's the code:
export const fetchUserBookmarks = ( bookmarksIDs ) => async ( dispatch, getState, api ) => {
dispatch({
type: 'IS_FETCHING_BOOKMARKS'
});
try {
bookmarks = [];
bookmarksIDs.forEach( bookmarkID => {
const bookmark = await api.get( selectedPostByIdEP + bookmarkID );
bookmarks.push( bookmark );
});
dispatch({
type: 'HAS_FETCHED_BOOKMARKS',
payload: bookmarks
});
} catch( error ) {
dispatch({
type: 'FAILED_FETCHING_BOOKMARKS',
payload: error
});
}
}
Upvotes: 1
Views: 11013
Reputation: 140
forEach loop is not compatible with promise and async functions. Use
for.. of
loop instead. It would work fine.
async(data)=>{
const ids = ["xyz","abc"]
for (const id of ids){
let data = await Collection.findById(id)
console.log(data)
}
}
Upvotes: 1
Reputation: 3210
First, To use await
you should declare the function as async
. You have done so with the outer function but not with the inner function.
The change will look something like this:
bookmarksIDs.forEach(async bookmarkID => {
Second, what you probably want is to run those api calls in parallel.
You can replace forEach
with a map
call and await all the resulting promises together.
To do that your code should look something like this:
const bookmarks = await Promise.all(
bookmarksIDs.map(bookmarkID =>
api.get( selectedPostByIdEP + bookmarkID )
)
);
--
It seems that if bookmarks
is not declared anywhere else it causes a problem. using const
or let
should solve that problem.
Upvotes: 8
Reputation: 224857
forEach
isn’t a loop; it’s a function that you pass a function to. There’s no way to get a promise out of it. If you want to perform api.get
s one by one, you can use a for loop:
for (const bookmarkID of bookmarksIDs) {
const bookmark = await api.get(selectedPostByIdEP + bookmarkID);
bookmarks.push(bookmark);
}
and if you want to do them in parallel, you can create several promises and use Promise.all
to collect their results:
const bookmarks = await Promise.all(
bookmarksIDs.map(
bookmarkID => api.get(selectedPostByIdEP + bookmarkID)
)
);
Upvotes: 1
Reputation: 1
You'll want to do something like this instead
try {
bookmarks = await Promise.all(bookmarksIDs.map( bookmarkID => api.get( selectedPostByIdEP + bookmarkID ));
dispatch({
type: 'HAS_FETCHED_BOOKMARKS',
payload: bookmarks
});
}
Upvotes: 0