Luiz Alves
Luiz Alves

Reputation: 2645

Promise with nodejs, how could I chain results

I am using mongodb with mongoose.

I have the some collections with the next models:

a. Model: Product

b. Model: Details

I need return a dataset with the total items in Product, and to each product item, i need calculate the quantity by loop your details in Model Details.

My problem is how do I could set the quantity in my data array, after execute the "promise_3". I´d need to know the index of the data array to do it, but How could I do it?

The result will be something as:

response:{
total:1012, 
data:[
{id:'1',name:'xx', quantity:10},
{id:'2',name:'yy', quantity:110},
{id:'3',name:'zz', quantity:130},
...
]}

//my code with the promises

var response={};
var promise_1=Product.count({}).lean().exec();

var prommise_2=function (data){
       return Product.find(conditions)
        .limit(pageSize)
        .skip(pageSize*(pageNumber-1))
        .sort(oorder)
        .lean()
        .exec();
   }


var prommise_3= function (item){
        return Details.aggregate(
                    [
                            { "$match": { 
                                cod_material: item._id
                            }},
                            {$lookup:
                              {
                                from: "estoqueMov", //use the name of database collection not mongoose model
                                localField: "cod_mov",
                                foreignField: "_id",
                                as: "mov_doc"
                              }
                            },

                            { $unwind: "$mov_doc" },
                            {$lookup:
                              {
                                from: "Details", //use the name of database collection not mongoose model
                                localField: "mov_doc.cod_tipo_mov",
                                foreignField: "_id",
                                as: "tipo_mov_doc"
                              }
                            },

                            { $unwind: "$tipo_mov_doc"},
                            { "$group": {
                                _id: "$cod_material",
                                total: { "$sum": 
                                        {"$multiply": 
                                         ["$quantidade",{"$cond":[
                                         {"$eq":["$tipo_mov_doc.tipo","Entrada"]} , 1,-1]}] 
                                        }
                                        } 
                            }}

                    ]);
    }

    //promise_1 is done
    promise_1.then( function(count){
         response.total=count;
         return promise_2() 
    })
    .then( function (data){
        response.data=data;
        for (var i = 0; i < response.data.length; i++) { 
          var item=response.data[i];
          //??item.quantity=0;
          return promise_3(item) 
        }
    })
    .then( function (results){
        var total=results.length>0?results[0].total:0;
        //Here is my problem How could I set the response.data index array??
        response.data[??????].quantity=total;
        callback(null,response,res);

    });

Upvotes: 0

Views: 89

Answers (1)

88jayto
88jayto

Reputation: 707

For this snippet, you should utlize Promise.all Since what you're trying to do is actually resolve 1 promise for each item inside your the array.

.then( function (data){
        response.data=data;
        for (var i = 0; i < response.data.length; i++) { 
          var item=response.data[i];
          //??item.quantity=0;
          return promise_3(item) 
        }
    })

It will look something like this

 .then( function (data){
            var promises = [];
            response.data=data;
            for (var i = 0; i < response.data.length; i++) { 
              var item=response.data[i];
              //??item.quantity=0;
              promises.push(promise_3(item)); 
            }
            return Promise.all(promises);
        })

Now essentially your next .then will not run until all promises in the promises array have been resolved.

NOTE: Order of the resulting promise.all array does maintain it's element order after completely resolving.

Given that the last .then will now be getting an array of data you will want to wrap its functionality inside a loop-- something like this (not 100% sure if this is what you want it to do, but you should get the idea.):

 for (var i = 0; i < results.length; i++) { 
          var total=results[i].length>0?results[i].total:0;
          response.data[i].quantity=total; 
 } 

Upvotes: 2

Related Questions