0

I'm new to using mongoose middleware and don't know if I'm following it well. Here is the purpose. After saving department, I want to populate university and save departmentId inside university object.

DepartmentSchema.post('save', function(next) {

  var departmentId = this._id;

  University.findOne({
    _id: this.university
  }, function(err, university) {
    if (!university.departments) {
      university.departments = [];
    }
    university.departments.push(new ObjectId(departmentId));
    university.save(function(err) {
      if (err) return console.log('err-->' + err);
      // saved!
    });
  });

});

This is working fine but I'm not sure why in Cascade style delete in Mongoose they have used exec() and next() calls. Could you please tell me the purpose of these calls? I don't know what they do and not able to find relevant documentation. I just want to make sure I'm not missing anything.

clientSchema.pre('remove', function(next) {
  // 'this' is the client being removed. Provide callbacks here if you want
  // to be notified of the calls' result.
  Sweepstakes.remove({
    client_id: this._id
  }).exec();
  Submission.remove({
    client_id: this._id
  }).exec();
  next();
});
Community
  • 1
  • 1

1 Answers1

2

Post middleware doesn't have reference to the next function and you cant do any flow control. Its actually passing the department that just got saved, so your code can be something like this:

DepartmentSchema.post('save', function(department) {
  var departmentId = department._id;

In pre middleware you have access to the next middleware in the order of execution. Which is the order of definition on a particular hook.

// hook two middlewares before the execution of the save method
schema.pre('save', pre1);
schema.pre('save', pre2);
function pre1(next) {
  // next is a reference to pre2 here
  next()
}
function pre2(next) {
  // next will reference the hooked method, in this case its 'save'
  next(new Error('something went wrong');
}
// somewhere else in the code
MyModel.save(function(err, doc) {
 //It'll get an error passed from pre2
});

Mongoose also gives you the ability to execute pre middlewares in parallel, in this case all middlewares will be executed in parallel but hooked method will not execute till the done is called from each middleware.

As for the exec() function, there are two ways of executing a query in Mongoose, either pass a callback to the query or chain it with an exec(): User.remove(criteria, callback) or User.remove(criteria).exec(callback), if you don't pass a callback to the query, it'll return a query object and it won't execute unless you chain it with exec()

teleaziz
  • 2,220
  • 1
  • 19
  • 25
  • This is a great insight. Where do you find this information? I don't see this in the official documentation. Did you learn these things by jumping in the source code? – Saurabh Gupta Mar 13 '15 at 23:14
  • Now when I look at the documentation, I'm finding this information there. – Saurabh Gupta Mar 13 '15 at 23:17
  • Thanks, glad it helped, as you figure out by now it's all in the docs, but mongoose docs is a little bit less verbose than it should be :) – teleaziz Mar 14 '15 at 02:59