2

I am using this forEach loop to push some data into array and send that to client side

   var arrayToSend = []  //Empty Array

   SomeArray.forEach(function(item){
        Collection.findById(item.id,function (err,data) {
          if (err) {
            console.log(err)
          } else {

            arrayToSend.push(data.record)
          }
  //How can I run this next line at end of loop  asynchronously
         res.render("index",{arrayToSend : arrayToSend })
        })
      })


    }

How can I use async to run res.render("index",{arrayToSend : arrayToSend }) after an loop end within forEach scope in form of callback,otherwise if I run this outside the loop it will send empty array ?

Saurabh
  • 1,592
  • 2
  • 14
  • 30

1 Answers1

1

Instead of .forEach, use .map to map each item in someArray to a Promise, so that you can create an array of Promises. If you call Promise.all on that array, you'll get a Promise that resolves when all of the promises in the array have resolved.

Because findById is callback-based, not Promise-based, you need to transform each callback into a Promise first:

const promises = someArray.map((item) => new Promise((resolve, reject) => {
  Collection.findById(item.id, (err,data) => {
    if (err) return reject(err);
    resolve(data.record);
  });
}));
Promise.all(promises)
  .then(arrayToSend => {
    res.render("index", { arrayToSend });
  })
  .catch((err) => {
    // handle errors
  });

If you want to tolerate errors from findById and still build an arrayToSend without the items that had errors, you can push to an external array (similar to what you were doing originally) and resolve unconditionally, whether findById results in an error or not:

const arrayToSend = [];
const promises = someArray.map((item) => new Promise((resolve, reject) => {
  Collection.findById(item.id, (err,data) => {
    if (err) console.log(err);
    else arrayToSend.push(data.record);
    resolve();
  });
}));
Promise.all(promises)
  .then(() => {
    res.render("index", { arrayToSend });
  })
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320