Tom Oakley Tom Oakley - 6 months ago 123
Node.js Question

'this' is undefined in a Mongoose pre save hook

I have made a Mongoose database schema for a User entity, and want to add the current date in an

updated_at
field. I am trying to use the
.pre('save', function() {})
callback but every time I run it I get an error message telling me
this
is undefined. I've also decided to use ES6, which I guess could be a reason for this (everything works though). My Mongoose/Node ES6 code is below:

import mongoose from 'mongoose'

mongoose.connect("mongodb://localhost:27017/database", (err, res) => {
if (err) {
console.log("ERROR: " + err)
} else {
console.log("Connected to Mongo successfuly")
}
})

const userSchema = new mongoose.Schema({
"email": { type: String, required: true, unique: true, trim: true },
"username": { type: String, required: true, unique: true },
"name": {
"first": String,
"last": String
},
"password": { type: String, required: true },
"created_at": { type: Date, default: Date.now },
"updated_at": Date
})

userSchema.pre("save", (next) => {
const currentDate = new Date
this.updated_at = currentDate.now
next()
})

const user = mongoose.model("users", userSchema)
export default user


The error message is:

undefined.updated_at = currentDate.now;
^
TypeError: Cannot set property 'updated_at' of undefined


EDIT: Fixed this by using @vbranden's answer and changing it from a lexical function to a standard function. However, I then had an issue where, while it wasn't showing the error anymore, it wasn't updating the
updated_at
field in the object. I fixed this by changing
this.updated_at = currentDate.now
to
this.updated_at = currentDate
.

Answer

the issue is your arrow function uses lexical this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

change

userSchema.pre("save", (next) => {
  const currentDate = new Date
  this.updated_at = currentDate.now
  next()
})

to

userSchema.pre("save", function (next) {
  const currentDate = new Date
  this.updated_at = currentDate.now
  next()
})
Comments