Проблема заключается в том, что bcrypt.hash(..., function(err, hash) { ... })
вызывает обратно предоставленный обратный вызов асинхронно
, следовательно,
this.updated_at = currentDate;
this.date = currentDate;
this.pin = pin;
console.log("Pin is " + pin)
// etc
будет выполняться раньше
pin = hash;
имеет шанс на запуск.
Существует три варианта
Чтобы правильно использовать обратные вызовы, поместите ВСЕ код, который опирается на hash
внутри обратного вызова
userSchema.pre('save', function(next) {
const currentDate = new Date();
// 10 defines salt rounds
let pin = this.cards[0].pin;
bcrypt.hash(pin, 10, (err, pin) => {
if (!err) {
this.updated_at = currentDate;
this.date = currentDate;
this.pin = pin;
console.log("Pin is " + pin)
if (!this.created_at) this.created_at = currentDate;
}
next(err);
})
});
выше без функций стрелок (но вы используете let
в своем коде, поэтому вы должны знать функцию стрелок, я надеюсь - на всякий случай)
userSchema.pre('save', function(next) {
const currentDate = new Date();
// 10 defines salt rounds
let pin = this.cards[0].pin;
let _this = this; // save _this for the callback
bcrypt.hash(pin, 10, function(err, pin) {
if (!err) {
_this.updated_at = currentDate;
_this.date = currentDate;
_this.pin = pin;
console.log("Pin is " + pin)
if (!_this.created_at) _this.created_at = currentDate;
}
next(err);
})
});
или, используя Promises
userSchema.pre('save', function(next) {
const currentDate = new Date();
// 10 defines salt rounds
let pin = this.cards[0].pin
bcrypt.hash(pin, 10).then((pin) => {
this.updated_at = currentDate;
this.date = currentDate;
this.pin = pin;
console.log("Pin is " + pin)
if (!this.created_at) this.created_at = currentDate;
next();
}).catch((err) => {
next(err);
})
});
и, наконец, использование async / await
userSchema.pre('save', async function(next) {
const currentDate = new Date();
// 10 defines salt rounds
let pin = this.cards[0].pin
try {
pin = await bcrypt.hash(pin, 10);
} catch(err) {
return next(err);
}
this.updated_at = currentDate;
this.date = currentDate;
this.pin = pin;
console.log("Pin is " + pin)
if (!this.created_at) this.created_at = currentDate;
next();
});
Существует четвертый вариант, но никогда не будет веской причины для .hash
синхронно