在mongoose中执行预更新时,user.isModified不是函数

oogrdqng  于 2023-04-06  发布在  Go
关注(0)|答案(7)|浏览(108)

我试图在我正在构建的应用程序中散列密码,当我通过调用此函数(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

但当我做一个更新,并有这个前:

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

我得到TypeError: user.isModified is not a function,如果我控制台日志用户在pre保存pre日志用户我更新,findandupdate pre不,id有办法访问文档在pre或我需要这样做的另一种方式?

ff29svar

ff29svar1#

你会得到一个错误,因为箭头函数改变了'this'的作用域。

UserSchema.pre('save', function(next){})
oymdgrw7

oymdgrw72#

我有一个类似的问题上typescript和它原来是有关的箭头运算符你也使用.不知道如何改变这在coffescript现在,但我认为这应该解决你的问题.
你必须改变这一行:

hashPass = (user, next) ->

看看这个https://github.com/Automattic/mongoose/issues/4537

eqfvzcg8

eqfvzcg83#

在mongoose中使用中间件时要小心,在“保存”或“updateOne”的情况下,this引用的是查询,而不是文档。

schema.pre(type, { document: true, query: false }, async function (next) 
{
     if(this.isModified('password')) {
            //Do the hash
     }
     next();
});
voase2hg

voase2hg4#

不要在回调函数中使用箭头操作符,这会改变作用域this。定义一个常规函数;它可以帮助你解决这个问题。

8ulbf1ek

8ulbf1ek5#

我知道这对你来说可能太晚了,但对于任何未来的程序员来说,这个问题,我认为这个解决方案应该工作。所以,由于保存()是.pre中的中间件,它覆盖了mongoose的一些方法,如findByIDAndUpdate。如果你有补丁请求在某处触发,你可能想做的是像这样分解你的代码,而不是使用它:

const user = await User.findById(req.params.id);
    updates.forEach((update) => {
      user[update] = req.body[update];
    });
vxf3dgd4

vxf3dgd46#

将箭头函数改为普通函数。这样,这个变量的作用域就不会改变。这段代码对我来说工作正常

x759pob2

x759pob27#

让它用常规函数代替箭头函数,箭头函数改变了这个范围。

相关问题