有人可以弄清楚我的代码有什么问题吗?
从文档中看来,Mongoose this
方法中的.pre('save')
应该是模型本身,但在下面的代码中this
最终会成为一个空对象。
const Mongoose = require('./lib/database').Mongoose;
const Bcrypt = require('bcrypt');
const userSchema = new Mongoose.Schema({
email: { type: String, required: true, index: { unique: true } },
password: { type: String, required: true }
});
userSchema.pre('save', (next) => {
const user = this;
Bcrypt.genSalt((err, salt) => {
if (err) {
return next(err);
}
Bcrypt.hash(user.password, salt, (err, encrypted) => {
if (err) {
return next(err);
}
user.password = encrypted;
next();
});
});
});
const User = Mongoose.model('User', userSchema);
保存用户时,我收到以下错误[Error: data and salt arguments required]
。
function createUser(email, password, next) {
const user = new User({
email: email,
password: password
});
user.save((err) => {
if (err) {
return next(err);
}
return next(null, user);
});
}
createUser('test@email.com', 'testpassword', (err, user) => {
if (err) {
console.log(err);
}
else {
console.log(user);
}
process.exit();
});
如果我删除.pre('save')
,那么它当然可以保存。我正在使用的Mongoose版本是4.2.6。
答案 0 :(得分:6)
这里的问题是fat arrow functions。您必须使用简单的函数重写回调。这里显示diff
的小例子var obj = {};
obj.func1 = function () {
console.log(this === obj);
};
obj.func2 = () => {
console.log(this === obj);
};
obj.func1(); // true
obj.func1.bind(obj)(); // true
obj.func2(); // false
obj.func2.bind(obj)(); // false
答案 1 :(得分:5)
我能够找出问题所在。事实证明,ES6中的箭头函数保留了声明范围的上下文,而不是使用调用范围的上下文,因此将代码更改为下面修复了问题。
userSchema.pre('save', function (next) {
Bcrypt.genSalt((err, salt) => {
if (err) {
return next(err);
}
Bcrypt.hash(this.password, salt, (err, encrypted) => {
if (err) {
return next(err);
}
this.password = encrypted;
next();
});
});
});
感谢Michelem让我认为ES6可能是罪魁祸首。
答案 2 :(得分:0)
我认为应该是:
userSchema.pre('save', (next) => {
var user = this;
// Try this
// console.log(user);
Bcrypt.genSalt(function (err, salt) {
if (err) {
return next(err);
}
Bcrypt.hash(user.password, salt, null, function (err, encrypted) {
if (err) {
return next(err);
}
user.password = encrypted;
next();
});
});
});
但请检查用户是否是正确的对象。