Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

user.isModified is not a function when doing a pre update in mongoose

I'm trying to hash passwords in an app I'm building and they are hashing fine when I create a user by calling this function(coffeesctipt):

UserSchema.pre 'save', (next) ->
  user = this
  hashPass(user, next)

hashPass = (user, next) ->
  # only hash the password if it has been modified (or is new)
  if !user.isModified('password')
    return next()
  # generate a salt
  bcrypt.genSalt SALT_WORK_FACTOR, (err, salt) ->
    if err
      return next(err)
    # hash the password using our new salt
    bcrypt.hash user.password, salt, (err, hash) ->
      if err
        return next(err)
      # override the cleartext password with the hashed one
      user.password = hash
      next()
      return
    return

but when I do an update and have this pre:

UserSchema.pre 'findOneAndUpdate', (next) ->
  user = this
  hashPass(user, next)

I get TypeError: user.isModified is not a function if I console log user in the pres the save pre logs the user I am updating , the findandupdate pre does not,id there to way to access the document in the pre or do I need to do this another way?

like image 626
jmona789 Avatar asked Oct 20 '16 18:10

jmona789


4 Answers

You get an error because the arrow function changes the scope of 'this.' Just use

UserSchema.pre('save', function(next){})
like image 174
lloyd agola Avatar answered Nov 12 '22 13:11

lloyd agola


I had a similar issue on typescript and it turns out that is was related to the arrow operator you are also using. Not sure how to change this in coffescript right now but I think that should fix your issue.

you have to change this line:

hashPass = (user, next) ->

Check this out: https://github.com/Automattic/mongoose/issues/4537

like image 45
orlaqp Avatar answered Nov 12 '22 13:11

orlaqp


Be careful when using middleware in mongoose, in that case of "save" or "updateOne", this refers to a query, not a document. It should look like this

schema.pre(type, { document: true, query: false }, async function (next) 
{
     if(this.isModified('password')) {
            //Do the hash
     }
     next();
});
like image 1
hiep ninh Avatar answered Nov 12 '22 13:11

hiep ninh


Don't use the arrow operator for the callback, that'll change the scope this. Define a regular function; it may help you to solve this problem.

like image 1
Nahid Estes Avatar answered Nov 12 '22 14:11

Nahid Estes