ocespedes
ocespedes

Reputation: 1303

Loop to get asynchronous data in nodejs sequelize

I'm working with nodejs and sequelize framework but I'm having issues trying to retrieve some data

getAllMedicamentsWithTotal: function () {
    return medicamentService.getAll().then(function success(medicaments) {
        for(var i = 0 ; i < medicaments.length; i++){
            getTotalMedicament(medicaments[i]).then(function (total) {
                medicaments[i].dataValues.total = total;
            })
        }
    }, function fail() {

    })
}

I have this function who gets all the medicament with its total in the stock. But the outer promise end before the callback its executed. I know there is an error over looping promises but is there a better way to do this than fixing this piece of code?

To give a little more context I have a table inventory who has a foreign key to the table medicaments, and in the inventory table there is the quantity of the medicaments. I want to get something like [{name1, sum(stockQuantity1)}, {name2, sum(stockQuantity2)}, ...] but I cant manage to do so.

I would appreciate any help

Upvotes: 0

Views: 1219

Answers (1)

Daniel Lizik
Daniel Lizik

Reputation: 3144

You have to wrap everything in a promise like this

getAllMedicamentsWithTotal: function () {
  return new Promise((resolve, reject) => {

    // call your service first
    medicamentService
      .getAll()

      // with your array of results we need to map out an array of promises
      // then feed that array into Promise.all() 
      .then(medicaments => Promise.all(medicaments.map(med => {
        return getTotalMedicament(med);
      }))

      // the result of Promise.all() is an array of results
      // reduce the totals to get your accumulated total and resolve it to the caller
      .then(arrayWithTotals => {
        let total = arrayWithTotals.reduce((acc, obj) => acc += obj.dataValues.total, 0);
        resolve(total);
      });
  });

// elsewhere...

getAllMedicamentsWithTotal().then(total => { /** your total */ });

As an aside it looks like you are doing a lot of logic for something that can most likely be done with a join query. IIRC sequelize calls this the include property on your query object.

Upvotes: 1

Related Questions