Reputation: 323
i am first time using pre save middleware and getting a bit confusion in it.
It runs perfectly fine and also my save method is getting executed eventhough i am not calling the next()
case 1
tourSchema.pre('save', function () {
console.log('first middleware is getting called');
})
But when i do like this when next is declared inside the function params but i don't call the next() it hangs there and the save method is not getting executed
case 2
tourSchema.pre('save', function (next) {
console.log('first middleware is getting called');
});
But as soon as i call the next() it gets executed
case 3
tourSchema.pre('save', function (next) {
console.log('first middleware is getting called');
next()
});
so i only want to know what's the wrong with the second case . In this i have only and only this pre middleware . How defining the next inside the function params can matter, the save method should also be executed in the second case since i don't have any second pre middleware.
Upvotes: 1
Views: 2202
Reputation: 461
thammada's answer perfectly explains your issue, I just want to add and say you can actually use an async function to escape the obligation to call next()
Pre middleware functions are executed one after another, when each middleware calls next.
`const schema = new Schema(..);
schema.pre('save', function(next) {
// do stuff
next();
});`
In mongoose 5.x, instead of calling next() manually, you can use a function that returns a promise. In particular, you can use async/await.
schema.pre('save', function() {
return doStuff().
then(() => doMoreStuff());
});
Upvotes: 0
Reputation: 5245
mongoose uses kareem library to manage hooks.
kareems
makes use of the length
property of your hook function to determine whether next
is defined as an argument or not.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length
Your first function has no arguments, kareem
will assume this is a sync function
const firstFunction = function () {
console.log('first middleware is getting called');
})
console.log(firstFunction.length) // this will output 0
Your second function has 1 argument, the kareem
library will see your function accept next
arguments. It will pass a callback and execute it in the next
function. Since next
is never called, that callback will be never called.
const secondFunction = function (next) {
console.log('first middleware is getting called');
})
console.log(secondFunction.length) // this will output 1
Upvotes: 1