我需要在另一个前置中间件中重用一个前置中间件功能,因为我提取了这样一个功能:
async function encryptPassword(next) {
if (!this.isModified('password')) {
return next();
}
this.password = await bcrypt.hash(this.password, 5);
this.passwordChangedAt = new Date();
next();
}
UserSchema.pre('save', encryptPassword);
UserSchema.pre("findOneAndUpdate", encryptPassword);
但是我收到一个错误消息,说this.isModified
不是函数,我假设this
指的是其他内容。该如何解决?
答案 0 :(得分:1)
在调试器和文档的帮助下,我深入了这些前/后钩子,发现了几件事情(它们同时适用于pre
和post
):
使用save
钩子意味着this
引用文档本身。因此,您可以更新其字段,调用isModified
之类的方法,等等。以上方法应该不会有任何问题。
但是,findOneAndUpdate
钩子意味着this
引用的是查询而不是文档。 Query对象将没有文档或其继承的方法(如isModified
)。
我与调试器进行了检查,可以确认是否是这种情况(有关文档的最新信息)。
钩子列表:https://mongoosejs.com/docs/middleware.html#types-of-middleware
您将看到只有以下挂钩允许修改文档:
validate
save
remove
updateOne
deleteOne
init (note: init hooks are synchronous)
其他所有人都不会。看来这是故意的(https://github.com/Automattic/mongoose/issues/964)。
要解决findOneAndUpdate
的问题,似乎(最相似)唯一的方法是将findOne
和updateOne
做为单独的查询进行重做。