0

I have been trying to use promises to fulfill assign people to shifts by finding the person who has worked in the least amount of time. To this I'm using aggregate to link each individual person's availability document with their record document that contains the last time they worked. It seems it is skipping over the whole section of code that has to do with promises because it is printing selectedPeopleList as an empty array. Here's my code:

var selectedPeopleList = [];

var sequentially = function(shifts) {

var p = Promise.resolve();

shifts.forEach(function (){
   p=p.then( function() { return collection.aggregate([
       {
          $lookup: 
            {
              from: "personRecord",
              localField: "ATTU_ID",
              foreignField: "ATTU_ID",
              as: "record"
            } 
        },

        {
          $match : { 'Available[]' : { $elemMatch : { $eq : shift.value } }, "record.ATTU_ID": { $nin : _.map(selectedPeopleList, 'ATTU_ID') } }
        },

        { 
          $sort : { "record.lastShift" : 1 }
        }
          ]).toArray(function(err, docs){ 
            assert.equal(err, null);

          }).then(function (result) {
            if(docs && docs.length) {
              selectedPeopleList.push({ ATTU_ID : docs[0].ATTU_ID, Name: docs[0].Name });
              console.log(docs[0]);
            }
          });
        });            
  })
  return p;
};
console.log(selectedPeopleList);

2 Answers2

2

Promises don't make asynchronous code synchronous

change that last line to

p.then(function() {
    console.log(selectedPeopleList);
});

also, you don't need to return anything in the forEach, as the return value isn't used at all

Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
0

There are quite a few small mistakes in your code.

Make sure you follow your async code flow properly. i tried to address all the issues in my snippet.

var selectedPeopleList = [];

var sequentially = function(shifts) {

var p = Promise.resolve();
//use promise all to merge all promises in to 1. and use map to return the promises.
Promise.all(shifts.map(function (){
   p=p.then( function() { return collection.aggregate([
       {
          $lookup: 
            {
              from: "personRecord",
              localField: "ATTU_ID",
              foreignField: "ATTU_ID",
              as: "record"
            } 
        },

        {
          $match : { 'Available[]' : { $elemMatch : { $eq : shift.value } }, "record.ATTU_ID": { $nin : _.map(selectedPeopleList, 'ATTU_ID') } }
        },

        { 
          $sort : { "record.lastShift" : 1 }
        }
          ]).toArray(function(err, docs){ 
            assert.equal(err, null);
          })
   })//make sure you finish then! before you start a new one.
   
   .then(function (result) {
            console.log('our results', result);
            if(result && result.length) { //use result variable!
              selectedPeopleList.push({ ATTU_ID : result[0].ATTU_ID, Name: result[0].Name });
              
            }
         
        });            
  })

  return p;
})
)
.then(function(){ //lets await all the promises first. and then read the list.
  
  console.log(selectedPeopleList);
  });
Joel Harkes
  • 10,975
  • 3
  • 46
  • 65
  • I made the edits you suggested; however, now the selectedPeopleList array is not printing. Actually nothing is printing out to the console. – user7438390 Jan 24 '17 at 03:21
  • sorry i still had some wrong references to `docs` (should be `result`) can you run and see what it returns now? – Joel Harkes Jan 24 '17 at 03:26
  • I tried that as well and is still not printing anything out. Not even console.log("our results", result); – user7438390 Jan 24 '17 at 03:36
  • I need to know what errors your getting. It could be that your collection function is wrong or toArray is wrong. Since I can't test it, you'll have to do it yourself. Simple principle you need to know that what the first then returns is the first parameter in the callback of the following then(). The code outside these thens/promise is executed before the code inside the promise. – Joel Harkes Jan 24 '17 at 06:57