0

I'm using mongoose to do some operation in MongoDB. I'd like to seach all tasks created by user, then set value isPerforming to false and save it. Documentation says that mongoose query (with .exec() function) is promise. There's many tasks so I think to push them to array and do parallel save operations using Q.all([...]). The problem is when I try to do .push(). My code stops after first .push() operation. Is there any other way to do it?

 function stopUserTasks(userid) {

    var deferred = Q.defer();
    var query = Task.find({'_creator': userid}).exec();

    query.then(function(data, err) {
        console.log('found: ');
        console.log(data);
        if (err) {
          deferred.reject(err);
        }
        return data;
      })
      .then(function(data, err) {

        var len = data.length;
        var saveTasksPromises = [];

        for(var i = len; i--; ) {
          console.log(data[i]._id);
          saveTasksPromises.push(Task.save({'_id': data[i]._id, 'isPerforming': false}).exec() );
        }
        return saveTasksPromises;

      })
      .then(function(data, err) {
        console.log(data);

        deferred.resolve();
      });

      return deferred.promise;

  }// #stopUserTasks
1
  • Please don't use the explicit promise creation antipattern. If you have to convert one type of promises (mongoose) to another (q), use Promise.resolve(otherPromise) or Q(otherPromise). Commented Nov 16, 2016 at 16:45

1 Answer 1

1

Model.save() returns promise actually, so no need to write Model.save().exec() so your line need to be adjusted as follow:

saveTasksPromises.push(Task.save({'_id': element._id, 'isPerforming': false}))

Also using Q.all, the whole function could be as follow:

function stopUserTasks(userid) {
  var deferred = Q.defer();
  var promise = Task.find({'_creator': userid}).exec();

  promise
    .then(function(data) {
      var len = data.length;
      var saveTasksPromises = [];

      for(var i = len; i--; ) {
        saveTasksPromises.push(Task.save({'_id': data[i]._id, 'isPerforming': false}));
      }
      return Q.all(saveTasksPromises);
    })
    .then(function(data) {
      deferred.resolve(data);
    });
    .catch(function(err) {
      deferred.reject(err);
    });
    return deferred.promise;
}
Sign up to request clarification or add additional context in comments.

5 Comments

It's not working. deferred promise isn't resolved or rejected. In console appear only first data._id. Of course element._id should be replaced by data[i]._id.
Check the edited answer above, after putting Q.all in action.
It almost work.. I figure out by myself how to do it thanks to yours suggestions. It works when in loop we change saveTasksPromises.push(Task.save({'_id': data[i]._id, 'isPerforming': false})); to var task = data[i]; task.isPerforming = false; saveTasksPromises.push(task.save());
Please don't use the explicit promise creation antipattern. If you have to convert one type of promises (mongoose) to another (q), use Promise.resolve(otherPromise) or Q(otherPromise).
@Tamas Hegedus : Thanks to point it out. I'm rookie but It isn't excuse to code in bad way :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.