hugger
hugger

Reputation: 488

Finish entire loop / forEach before next command

I had this working until I added a few more commands after the forEach. Basically when a post gets deleted the primary goal is to remove it from user's feeds (which was working). I then chained the 4 .then() and now it is only looping once then completes the rest of the processes... How can I make sure it loops then entire collection before it continues?

Here is what my code looks like:

    exports.updateFeedDelete = functions.database.ref('/categories/{postId}')
      .onDelete((snapshot, context) => {

      //...

      const followersRef = admin.database().ref(`friends/${friendId}`);

      return followersRef.once("value", function(snap) {
        snap.forEach(function(childSnapshot) {
          const followerId = childSnapshot.key;
          //FINISH ALL LOOPS HERE?
          return admin.database().ref(`feed/${followerId}/${postId}`).remove();
        });
      })
      //DONT EXECUTE UNTIL ALL LOOPS ARE DONE, NOT ONLY 1...
      .then(() => {
        //...
      })
      .then(() => {
        //...
      })
      .then(() => {
        //...
      })
      .then(() => {
        //...
    })

I appreciate all the help I can get with this, Cheers!

Upvotes: 1

Views: 62

Answers (1)

jfriend00
jfriend00

Reputation: 707228

If you want to know when a whole bunch of parallel operations are done, use the promise interface on your database to get a promise for each operation and use Promise.all() to monitor an array of promises and tell you when they are all done and then start the rest of your code when Promise.all() tells you everything is done.

I don't really know the firebase API, but from a little poking around in the doc, I think it could look something like this:

exports.updateFeedDelete = functions.database.ref('/categories/{postId}')
  .onDelete((snapshot, context) => {

  //...

  const followersRef = admin.database().ref(`friends/${friendId}`);

  return followersRef.once("value").then(snap => 
    let promises = [];
    snap.forEach(childSnapshot => {
      const followerId = childSnapshot.key;
      // do whatever else here.  If asynchronous, chain promises
      // so you're pushing one promise into the array that
      // represents when all this code is done
      promises.push(admin.database().ref(`feed/${followerId}/${postId}`).remove());
    });
    return Promise.all(promises);                                     
  }).then(() => {
    // code here will run after the snap.forEach() code is done
  }).catch(err => {
    // handle errors here
  });
})

Upvotes: 2

Related Questions