1

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
        });

    }

}
2
  • add async to forEach loop, bookmarksIDs.forEach(async bookmarkID => {...}) Commented Apr 9, 2018 at 6:56
  • 3
    sure, that would work, but not as expected, for example, dispatch will be called before anything is pushed to bookmarks regardless of what you do inside forEach - see this answer Commented Apr 9, 2018 at 6:56

4 Answers 4

8

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.

Sign up to request clarification or add additional context in comments.

8 Comments

How does the first step relate to the second step?
The first point is to show what's missing in your code. The second point is to show how to modify the code to run in parallel, if that is what you intended to do.
But async isn’t missing. Putting it there wouldn’t work at all.
You can't use await api.get in the inner without it. But I agree, that is why I prefer the solution in the second part of my answer.
@TalZ OP here. I've just tried your code (second part) but it doesn't seem to work for me. More precisely, the requests are being made and are successful (I can see that in the inspector's Network tab), but in fact any code that follows the Promise.all snippet doesn't execute. Even just a console.log prints nothing to the console...
|
1

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.gets 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)
    )
);

Comments

1

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)
    } 
}

Comments

0

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
    });

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.