I am making a REST API in NodeJS using the Mongoose Driver. I want to hash the passwords before saving them. For the same, I am using Mongoose Schema, where I made a userSchema for my user model. And for hashing I used the following function.
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();
});
But on creating a user or modifying it I am getting Error 500, and {} is getting returned. My routers are as follows.
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);
}
});
And the following is my console output.
Server running on port 3000
{}
undefined
On commenting out the userSchema.pre('save', ...) everything is working as expected. Please can you help me figure out where am I going wrong.
Using function definition instead of arrow function for mongoose pre
save middleware:
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();
});
Update:
The difference is this
context, if you use arrow
function in this line const user = this;
, this now is your current file (schema file, I guess).
When you use function
keyword, this
context will belong to the caller object (user instance).