arnoldssss
arnoldssss

Reputation: 488

Need to execute function when forEach functions ends

I have this code in node js / firebase :

ref.child("recipts").once("value", function(usersSnap) {
    usersSnap.forEach(function(reciptsSnap) {  
      reciptsSnap.forEach(function(reciptSnap) {

        reciptSnap.ref.child("last_recipt").once("value", function(b) {
          b.forEach(function(c) {  //Here I fill some "product" object
              });
        });

        reciptSnap.forEach(function(b) { //Here I fill some "product" object
        });

      });
    });
  });

I need to execute a function just when "reciptSnap" forEachs finished. How can I accomplish this, I try using a variable i++ and i-- but only work for one forEach iteration. The function I call is for manipulating the product object I created with the filled data from the forEachs loops.

Upvotes: 1

Views: 264

Answers (2)

Santanu Biswas
Santanu Biswas

Reputation: 4787

If I have understood correctly, you want to call a function when reciptsSnap.forEach is complete and all async tasks inside it are also complete.

For achieving this, you can use the index parameter and the original array that is passed to the callback function of forEach. (See Documentation)

The code will be like this:

(Note: The following code is without changing the current forEach loop structure used. However, re-writing the code with Promise or async would be a better & cleaner way to do it).

var loop1Done = false;
var loop2Done = false;

ref.child("recipts").once("value", function (usersSnap) {
    usersSnap.forEach(function (reciptsSnap) {
        reciptsSnap.forEach(function (reciptSnap, index, colA) {

            const idx = index;
            const col = colA;

            reciptSnap.ref.child("last_recipt").once("value", function (b) {

                const i = idx;
                const c = col;

                b.forEach(function (c, j, colB) {  //Here I fill some "product" object

                    // Do what you want here

                    // Check if all done for this loop
                    if ((j >= colB.length) && (i >= c.length)) {

                        loop1Done = true;

                        // Check if all loops done
                        if (loop1Done && loop2Done) {
                            // Call final callback function
                            // e.g. myFinalCallback();
                        }
                    }
                });
            });

            reciptSnap.forEach(function (b, k, colC) { //Here I fill some "product" object

                const i = idx;
                const c = col;

                // Do what you want here

                // Check if all done for this loop
                if ((k >= colC.length) && (i >= c.length)) {

                    loop2Done = true;

                    // Check if all loops done
                    if (loop1Done && loop2Done) {
                        // Call final callback function
                        // e.g. myFinalCallback();
                    }
                }
            });

        });
    });
});

Upvotes: 2

arneson
arneson

Reputation: 141

Try:

   reciptSnap.child("last_recipt").forEach(function(b) {
      b.forEach(function(c) {
               //Here I fill some "product" object
      });
   });

This should work since all of your data should already have been fetched when you did "value" on the receipts node.

If this works, your code is no longer asynchronous and right after the last forEach, you can execute the function you wanted to.

    reciptSnap.forEach(function(b) {
        //Here I fill some "product" object
    });
    //Execute your function here
  });

Upvotes: 1

Related Questions