遇到user.isModified is not a function报错,求助解决方法
解决"user.isModified is not a function"错误
问题根源
在Mongoose的updateOne预中间件里,this指向的是查询对象(Query),不是用户的文档实例。isModified是文档实例独有的方法,所以直接调用会报错。
解决方案
方案1:改用findOneAndUpdate中间件(推荐)
给findOneAndUpdate中间件加上context: 'document'选项,让this指向文档实例,这样就能正常使用isModified了,代码逻辑和你原来的几乎一致:
userSchema.pre('findOneAndUpdate', { context: 'document' }, function(next) { const user = this; if (!user.isModified('password')) return next(); bcrypt.genSalt((error, salt) => { if (error) return next(error); bcrypt.hash(user.password, salt, (error, hash) => { if (error) return next(error); user.password = hash; next(); }) }) })
方案2:继续使用updateOne(需手动处理)
如果一定要用updateOne,得从查询对象里获取更新数据,手动判断密码是否修改,还要查询旧文档避免重复哈希:
userSchema.pre('updateOne', function(next) { const update = this.getUpdate(); // 没有更新密码就直接跳过 if (!update.password) return next(); // 查询旧文档,对比密码是否变化 this.model.findOne(this.getQuery()) .then(oldUser => { if (oldUser.password === update.password) return next(); bcrypt.genSalt((error, salt) => { if (error) return next(error); bcrypt.hash(update.password, salt, (error, hash) => { if (error) return next(error); // 更新哈希后的密码 this.setUpdate({ ...update, password: hash }); next(); }) }) }) .catch(next); })
注意事项
context: 'document'选项需要Mongoose v5.2及以上版本支持- 方案1更符合你原本的代码逻辑,实现更简洁,优先推荐
内容的提问来源于stack exchange,提问作者Thiago Souza
相关产品推荐
相关产品推荐

