0

I have a node with the users list and a second node with the rating information for each user. I would like to loop within the users of the first node and for each one get the rating from the second node. The problem is that the loop doesn't wait for the second node to give the answer, therefore the array returned is always empty. I know I need to use await/async method but it's not working. Thanks for help

return admin.database().ref('/user').once('value').then(async(snap) => {
for(const userId of snap) {
    admin.database().ref('/rating/' + userId.key).once('value').then(await (snap) =>{
        var rating = snap.val();
        array.push([userId.key, rating]);
    }).catch(error => {
        console.log("failed 1 " + error.code);
    });
}
return array;
}).catch(error => {
console.log("failed 2 " + error.code);
});

1 Answer 1

1

You need to use Promise.all(), as follows (untested):

  const array = [];
  const userIds = [];
  return admin
    .database()
    .ref('/user')
    .once('value')
    .then((snap1) => {
      const promises = [];
      snap1.forEach((childSnapshot1) => {
        promises.push(
          admin
            .database()
            .ref('/rating/' + childSnapshot1.key)
            .once('value')
        );
        userIds.push(childSnapshot1.key);
      });
      return Promise.all(promises);
    })
    .then((snap2) => {
      snap2.forEach((childSnapshot2, idx) => {
        const rating = childSnapshot2.val();
        array.push([userIds[idx], rating]);
      });
      return array;
    })
    .catch((error) => {
      //...
    });

As explained in the Promise.all() doc, "returned values will be in order of the Promises passed, regardless of completion order". So for the userIds and snap2 arrays, their elements orders are corresponding: you can therefore do array.push([userIds[idx], rating]);

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

2 Comments

thanks that worked! would it be possible to achieve the same result with async/await?
Yes, it would be possible, but using async/await and forEach is not straightforward, see codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404.

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.