title: Node.js Promises: Push to array asynchronously & save
body: <p>I am currently trying to push to an array (attribute within a Mongo Model), from a list of items I receive through a request. From those items, I loop through them to see which one is currently in the db and if that is not the case, then I create a new Item and try to save it. I am using promises to accomplish this task but I am unable to figure out why the array is empty after all the promises have fulfilled. </p>
  
  <pre><code>var q     = require('q');
  
  var items_to_get = ['1', '2', '3']; // example array
  
  var trans = new Transaction({
      items   : []
  });
  
  var promises = [];
  
  for (var i = 0; i &lt; items_to_get.length; i++) {
  
    var ith = i; //save current i, kinda hacky
    var deferred = q.defer(); //init promise
  
    //find an existing item
    Item.findOne({simcode: items_to_get[ith]}, function(err, item) {
        trans.items.push(item); // push item to transaction
        deferred.resolve(item); // resolve the promise
    });
    promises.push(deferred); // add promise to array, can be rejected or   fulfilled
  };
  
  q.allSettled(promises).then(function(result) {
    console.log(trans.items); //is empty
    trans.save();
  }
  </code></pre>
  
  <p><strong>EDIT</strong> Resolved: Code bellow, based on <a href="http://jsbin.com/bufecilame/1/edit?html,js,output" rel="noreferrer">http://jsbin.com/bufecilame/1/edit?html,js,output</a> .. credits go to @macqm</p>
  
  <pre><code>var items_to_get = ['1', '2', '3'];
  var promises     = []; //I made this global
  
  items_to_get.forEach(item) {
    upsertItem(item);
  }
  
  q.allSettled(promises).then(function(result) {
    //loop through array of promises, add items 
    result.forEach(function(res) { 
      if (res.state === "fulfilled") {
        trans.items.push(res.value);
      }
    });
    trans.save();
    promises = []; //empty array, since it's global.
  }
  
  //moved main code inside here
  function upsertItem(item) {
    var deferred = q.defer(); //init promise
    //find an existing item
    Item.findOne({simcode: item}, function(err, item) {
      deferred.resolve(item); // resolve the promise
      // don't forget to handle error cases
      // use deffered.reject(item) for those
    });
    promises.push(deferred); // add promise to array
  }
  </code></pre>