As I described in the title when I want to save a new mongoose document the pre('save')
method fires, but the this
element in it is an emtpty object.
The test snippet:
var schema = new mongoose.Schema({
password:String
})
schema.pre('save',(next)=>{
console.log(this)
next()
})
var model = mongoose.model('Test',schema)
var test = new model({
password:'testpass'
})
test.save()
I cant see the problem with this basic code.
I am using Mongoose v4.5.9.
The save() function triggers validate() hooks, because mongoose has a built-in pre('save') hook that calls validate() . This means that all pre('validate') and post('validate') hooks get called before any pre('save') hooks.
To get the object ID after an object is saved in Mongoose, we can get the value from the callback that's run after we call save . const { Schema } = require('mongoose') mongoose. connect('mongodb://localhost/lol', (err) => { if (err) { console. log(err) } }); const ChatSchema = new Schema({ name: String }); mongoose.
Types. ObjectId . A SchemaType is just a configuration object for Mongoose. An instance of the mongoose. ObjectId SchemaType doesn't actually create MongoDB ObjectIds, it is just a configuration for a path in a schema.
The answer from user "unR" is correct. You can not use this
when you are using an arrow function on a pre save function. You will also find this on all other types of mongoose schema functions. I have expanded on this answer to help clarify why this occurs.
This breaks:
schema.pre('save', (next) => { // arrow function
console.log(this);
next();
});
This works:
schema.pre('save', function preSave(next) { // regular function
console.log(this);
next();
});
The reason:
The problem occurs because of how arrow functions treat "scope" differently to regular functions. Arrow functions do not keep scope within the function but rather forcefully inherit scope from the outside or surrounding function (this means it will overwrite functions such as exampleMethod.bind(this)
). In the case above; there is no outside function so the this
value would be equal to undefined
.
However, when you use the regular function declaration, the scope can be overwritten by mongoose using the .bind()
method. As such, they bind the function to the schema object which allows you to have access to the schema properties and functions within the function.
Here is a helpful resource on arrow functions and how they work: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
For whatever reason your function cannot have the es6 arrow syntax
schema.pre('save', function(next) {
console.log(this)
next()
})
Will work. I currently have no idea why.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With