Mongoose pre('save') hooks for password hashing
lifecycle hooks on documents.
pre('save') runs before persistence; use it to hash the password, guarding with isModified, calling next() or returning.
WHAT THIS TESTS This tests knowledge of Mongoose's document lifecycle hooks and the subtle correctness issues around this binding and re-hashing.
A GOOD ANSWER COVERS Mongoose middleware, also called hooks, are functions that run at defined points in a document's lifecycle. A pre('save') hook executes just before a document is persisted, making it the right place to transform or validate data in one centralized location instead of scattering logic across the app. For password hashing, you define schema.pre('save', function(next) { ... }) using a regular function, not an arrow function, because Mongoose binds this to the document being saved and arrow functions would lose that. Inside, you guard with if (!this.isModified('password')) return next(); so you only hash when the password actually changed, preventing a second hash of an already-hashed value on unrelated updates. Then you hash this.password (for example with bcrypt) and call next() or, in an async hook, simply await and return. This guarantees plaintext passwords never reach the database regardless of which code path triggers the save.
COMMON WRONG ANSWERS Using an arrow function, so this is not the document. Hashing on every save without the isModified guard, double-hashing passwords and breaking logins. Forgetting to call next() in callback style, hanging the save. Putting hashing logic in every controller instead of the model, risking missed paths.
LIKELY FOLLOW-UPS Why a regular function over an arrow function? What does isModified prevent? How do you compare passwords on login? What other hooks exist (pre validate, post save)?
ONE CONCRETE EXAMPLE userSchema.pre('save', async function(next) { if (!this.isModified('password')) return next(); this.password = await bcrypt.hash(this.password, 10); next(); }); Now any user.save(), from signup or password reset, hashes the password centrally, while updating only the user's email skips hashing because isModified('password') is false, avoiding a corrupting double hash.
Read the original → mongoosejs.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.