Tung Phi
Tung Phi

Reputation: 35

How mongoose middleware works and what is next()?

userSchema.pre('save',async function(next){
   //hash the password before saving user to database
   next()
})

Hey guys I'm trying to understand the concept of middleware in mongoose. Assuming that I have an userSchema that I run the pre hook on to hash the password before saving the user to the database. On the surface, as far as I understand, the above code that I have will hash the password (not the important part for this question) and then call next() to signal that the function is done. However, I am trying to understand how things work under the hood. I want to know what is next() ? Can you guys walk me through an example of how everything works together under the hood from start to end once the code get executed or somehow help me to have a better understanding of this concept? Thanks

Upvotes: 3

Views: 3692

Answers (1)

turbopasi
turbopasi

Reputation: 3625

Short : with the pre method you can register listeners for certain events of your Schemas. So pre('save', callback) will fire whenever you save a document of said Model. pre means it will execute before the event, so it can be used (for example) to hash a password before saving it to the document.

However, you have several options to define them, see below :

The combination of using an async callback function and providing the next parameter is not necessary, you can either :

use normal callback with next parameter

the next parameter is a function provided to you by mongoose to have a way out, or to tell mongoose you are done and to continue with the next step in the execution chain. Also it is possible to pass an Error to next it will stop the execution chain.

schema.pre('save', function(next) {
  // do stuff
  
  if (error) { return next(new Error("something went wrong"); }
  return next(null);
});

use async callback

Here the execution chain will continue once your async callback has finished. If there is an error and you want to break/stop execution chain you just throw it

schema.pre('save', async function() {
  // do stuff
  await doStuff()
  await doMoreStuff()

  if (error) { throw new Error("something went wrong"); }
  return;
});

Straight from the docs : https://mongoosejs.com/docs/middleware.html#pre

Example

const { Schema, model }  = require('mongoose');

const SomeSchema = new Schema ({
  name : { type : String }
});

SomeSchema.pre('save', function (next) {
  console.log('pre save fired!');
  return next();
});

const Some = model('Some', SomeSchema);

console.log('before create');
const doc = new Some({ name : 'test' });
doc.save((err) => {
  console.log('after saved');
});

This will output

before create
pre save fired!
after saved

Upvotes: 3

Related Questions