Bird
Raised Fist0
Expressframework~20 mins

Mongoose middleware (pre/post hooks) in Express - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Mongoose Middleware Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What happens when a pre-save hook modifies a document field?
Consider a Mongoose schema with a pre('save') hook that changes a field value before saving. What will be the final value stored in the database?
Express
const userSchema = new mongoose.Schema({ name: String, active: Boolean });
userSchema.pre('save', function(next) {
  this.active = true;
  next();
});
const User = mongoose.model('User', userSchema);

const user = new User({ name: 'Alice', active: false });
await user.save();
console.log(user.active);
Aundefined
Btrue
Cfalse
Dnull
Attempts:
2 left
💡 Hint
The pre-save hook runs before the document is saved to the database and can modify fields.
state_output
intermediate
2:00remaining
What is the output of a post-remove hook logging the removed document?
Given a Mongoose model with a post('remove') hook that logs the removed document, what will be printed after calling remove() on a document?
Express
const itemSchema = new mongoose.Schema({ name: String });
itemSchema.post('remove', function(doc) {
  console.log(doc.name);
});
const Item = mongoose.model('Item', itemSchema);

const item = new Item({ name: 'Book' });
await item.save();
await item.remove();
AError: remove is not a function
Bundefined
Cnull
D"Book"
Attempts:
2 left
💡 Hint
The post-remove hook receives the removed document as an argument.
📝 Syntax
advanced
2:00remaining
Which option correctly defines a pre-update hook using async/await?
You want to run code before updating a document using updateOne. Which code snippet correctly defines an async pre-update hook?
Aschema.pre('updateOne', async function(next) { await someAsyncTask(); next(); });
Bschema.pre('updateOne', function(next) { await someAsyncTask(); next(); });
Cschema.pre('updateOne', async function() { await someAsyncTask(); });
Dschema.pre('updateOne', function() { someAsyncTask().then(() => next()); });
Attempts:
2 left
💡 Hint
Async hooks can return a promise or use next callback, but mixing both can cause errors.
🔧 Debug
advanced
2:00remaining
Why does this post-save hook not log the updated document?
A developer writes this post-save hook but it logs the old document state instead of the updated one. Why?
Express
schema.post('save', function(doc) {
  console.log(doc.modifiedField);
});

await Model.findByIdAndUpdate(id, { modifiedField: 'newValue' });
AfindByIdAndUpdate does not trigger save middleware
Bpost-save hook only runs on new documents
CThe hook must be pre-save to see changes
DThe document passed to post-save is a copy, not updated
Attempts:
2 left
💡 Hint
Not all update methods trigger save middleware in Mongoose.
🧠 Conceptual
expert
2:00remaining
How does Mongoose handle errors thrown in async pre hooks?
If an async pre hook throws an error, what is the effect on the document operation?
AThe operation is aborted and the error is passed to the callback or promise rejection
BThe error is ignored and the operation continues normally
CThe error causes the server to crash immediately
DThe hook retries the operation automatically once
Attempts:
2 left
💡 Hint
Middleware errors usually stop the operation and propagate the error.

Practice

(1/5)
1. What is the main purpose of pre middleware in Mongoose?
easy
A. To connect to the MongoDB database
B. To run code after a database operation completes
C. To define the schema structure
D. To run code before a database operation like save or remove

Solution

  1. Step 1: Understand middleware timing

    Pre middleware runs before a database action, allowing preparation or validation.
  2. Step 2: Differentiate pre and post hooks

    Post middleware runs after the action, so pre is for before actions.
  3. Final Answer:

    To run code before a database operation like save or remove -> Option D
  4. Quick Check:

    Pre middleware = before action [OK]
Hint: Pre means before the action starts [OK]
Common Mistakes:
  • Confusing pre with post middleware
  • Thinking pre defines schema structure
  • Assuming pre connects to database
2. Which of the following is the correct syntax to add a pre-save hook in Mongoose?
easy
A. schema.on('save', function(next) { /* code */ next(); });
B. schema.pre('save', function(next) { /* code */ next(); });
C. schema.before('save', function() { /* code */ });
D. schema.post('save', function(next) { /* code */ next(); });

Solution

  1. Step 1: Recall Mongoose middleware method names

    Mongoose uses pre and post methods for middleware, not before or on.
  2. Step 2: Check syntax for pre-save hook

    The correct syntax is schema.pre('save', function(next) { ... next(); }); to run code before saving.
  3. Final Answer:

    schema.pre('save', function(next) { /* code */ next(); }); -> Option B
  4. Quick Check:

    Use schema.pre for pre hooks [OK]
Hint: Use schema.pre('event', fn) for pre hooks [OK]
Common Mistakes:
  • Using schema.post instead of schema.pre for pre hooks
  • Using non-existent methods like before or on
  • Forgetting to call next() in middleware
3. Given this Mongoose pre-save middleware, what will be the value of doc.updatedAt after saving?
schema.pre('save', function(next) {
  this.updatedAt = new Date();
  next();
});
medium
A. Undefined because updatedAt is not set in schema
B. The date when the document was created
C. The current date and time when save is called
D. An error because next() is missing

Solution

  1. Step 1: Understand pre-save middleware effect

    The middleware sets this.updatedAt to the current date before saving.
  2. Step 2: Confirm middleware runs before save

    Since it runs before save, the document's updatedAt will be updated to the current time.
  3. Final Answer:

    The current date and time when save is called -> Option C
  4. Quick Check:

    Pre-save sets updatedAt = now [OK]
Hint: Pre-save runs before saving, so updatedAt is current time [OK]
Common Mistakes:
  • Assuming updatedAt is undefined without schema field
  • Confusing createdAt with updatedAt
  • Thinking next() is missing causing error
4. What is wrong with this Mongoose middleware code?
schema.pre('remove', (next) => {
  console.log('Removing', this._id);
  next();
});
medium
A. Arrow function does not bind 'this', so 'this' is undefined inside middleware
B. Missing call to next() to continue middleware chain
C. Using 'remove' event is not supported in Mongoose
D. Middleware must be post, not pre, for remove

Solution

  1. Step 1: Check function type in middleware

    Mongoose middleware requires normal functions to bind this to the document.
  2. Step 2: Identify arrow function issue

    Arrow functions do not bind this, so this will be undefined inside the middleware.
  3. Final Answer:

    Arrow function does not bind 'this', so 'this' is undefined inside middleware -> Option A
  4. Quick Check:

    Use normal functions for middleware to access this [OK]
Hint: Use function() not arrow to access this in middleware [OK]
Common Mistakes:
  • Using arrow functions in middleware
  • Forgetting to call next() in async middleware
  • Thinking remove event is unsupported
5. You want to log a message after a document is saved and also update a cache. Which Mongoose middleware setup is correct?
hard
A. Use schema.post('save', function(doc) { console.log('Saved:', this._id); updateCache(this); });
B. Use schema.pre('save', function(doc) { console.log('Saved:', this._id); updateCache(this); });
C. Use schema.post('save', (doc) => { console.log('Saved:', this._id); updateCache(this); });
D. Use schema.pre('save', (doc) => { console.log('Saved:', this._id); updateCache(this); });

Solution

  1. Step 1: Identify when to run logging and cache update

    Logging and cache update should happen after saving, so use post middleware.
  2. Step 2: Choose correct function syntax

    Post middleware receives the saved document as first argument; use normal function to access this if needed.
  3. Final Answer:

    Use schema.post('save', function(doc) { console.log('Saved:', this._id); updateCache(this); }); -> Option A
  4. Quick Check:

    Post-save + normal function for logging/cache [OK]
Hint: Use post-save with normal function for after-save tasks [OK]
Common Mistakes:
  • Using pre instead of post for after-save tasks
  • Using arrow functions losing this context
  • Not passing doc argument in post middleware