#node.js #mongodb #mongoose
#node.js #mongodb #мангуст
Вопрос:
Я создаю REST API в NodeJS, используя драйвер Mongoose. Я хочу хэшировать пароли перед их сохранением. Для того же я использую схему Mongoose, где я создал пользовательскую схему для своей пользовательской модели. А для хеширования я использовал следующую функцию.
userSchema.pre('save', async (next) => {
const user = this;
console.log(user);
console.log(user.isModified);
console.log(user.isModified());
console.log(user.isModified('password'));
if (!user.isModified('password')) return next();
console.log('just before saving...');
user.password = await bcrypt.hash(user.password, 8);
console.log('just before saving...');
next();
});
Но при создании пользователя или его изменении я получаю ошибку 500, и возвращается {} . Мои маршрутизаторы выглядят следующим образом.
router.post('/users', async (req, res) => {
const user = User(req.body);
try {
await user.save();
res.status(201).send(user);
} catch (e) {
res.status(400).send(e);
}
});
router.patch('/users/:id', async (req, res) => {
const updateProperties = Object.keys(req.body);
const allowedUpdateProperties = [
'name', 'age', 'email', 'password'
];
const isValid = updateProperties.every((property) => allowedUpdateProperties.includes(property));
if (!isValid) {
return res.status(400).send({error: "Invalid properties to update."})
}
const _id = req.params.id;
try {
const user = await User.findById(req.params.id);
updateProperties.forEach((property) => user[property] = req.body[property]);
await user.save();
if (!user) {
return res.status(404).send();
}
res.status(200).send(user);
} catch (e) {
res.status(400).send(e);
}
});
И ниже приведен мой вывод на консоль.
Server running on port 3000
{}
undefined
При комментировании UserSchema.pre(‘save’, …) все работает так, как ожидалось. Пожалуйста, не могли бы вы помочь мне понять, где я ошибаюсь.
Ответ №1:
Использование определения функции вместо функции стрелки для pre
промежуточного программного обеспечения mongoose save:
userSchema.pre('save', async function(next) { // this line
const user = this;
console.log(user);
console.log(user.isModified);
console.log(user.isModified());
console.log(user.isModified('password'));
if (!user.isModified('password')) return next();
console.log('just before saving...');
user.password = await bcrypt.hash(user.password, 8);
console.log('just before saving...');
next();
});
Обновить:
Разница this
в контексте, если вы используете arrow
функцию в этой строке const user = this;
, теперь это ваш текущий файл (файл схемы, я полагаю).
При использовании function
ключевого this
слова контекст будет принадлежать вызывающему объекту (экземпляру пользователя).
Комментарии:
1. Спасибо. Это работает. Не могли бы вы объяснить, какая разница при использовании ключевого слова function, а не символа стрелки?
2. @hoangdy, можете ли вы также установить его асинхронную / синхронизирующую версию.
3. @Becauseihatemyself что вы имеете в виду?
4. Я имею в виду ответ в стиле async / await. bcrypt, генерирующий соль для хеширования в асинхронном ожидании.
5. @Becauseihatemyself Просто вызовите
hashSync
вместоhash
и удалитеasync
,await
. Но,async
способ рекомендуетсяbcrypt
.