mongoose 4.0.1: pre "update" middleware this object does not return model object
Problem
Hi, I've a problem with the newest version of Mongoose. I'm creating an API with Express and Mongoose 4.0.1, and I'm not sure if I'm doing anything wrong, but the fact is whenever I try to use the new `pre` update middleware the same way I use `pre` save middleware, `this` object does not return the object being updated, instead it returns the `Query` object. Example of what I'm trying to explain: [code block] [code block] This is what I get in `this` reference object within the middleware, and I don't know how it's useful to me. [code block] Looking at the source code, some of its properties are defined inside `Query` function defined in `./node_modules/mongoose/lib/query.js`: Is this something unexpected or I am doing anything wrong? It would be interesting to have a solution because I don't like the idea of validating within a middleware on object saving and being forced to run validations directly on controller when updating. The same thing happens with findOneAndUpdate `pre` middleware, but I don't expect it to return the exercise before finding it. In fact and in my honest opinion, I think it would be interesting that findAndUpdate and findOneAndUpdate pre middlewares triggered find(One) and update middlewares, in this order, instead of having its own middleware. Thanks in advance for your help.
Unverified for your environment
Select your OS to check compatibility.
1 Fix
Update Mongoose Middleware to Use `updateOne` or `findOneAndUpdate` Correctly
In Mongoose 4.0.1, the `pre` middleware for `update` and `findOneAndUpdate` operations does not provide the document being updated as `this`. Instead, it provides the `Query` object, which can lead to confusion when trying to validate or manipulate the document before the update. This behavior is by design, as Mongoose treats these operations differently compared to `save` operations.
Awaiting Verification
Be the first to verify this fix
- 1
Use `updateOne` or `findOneAndUpdate` with a separate `pre` middleware
Instead of relying on the `pre` middleware for `update`, create a separate middleware for `findOneAndUpdate` or `updateOne` that allows you to access the document being updated using `find` before the update occurs.
javascriptconst mongoose = require('mongoose'); const schema = new mongoose.Schema({ name: String }); schema.pre('findOneAndUpdate', async function(next) { const update = this.getUpdate(); const doc = await this.model.findOne(this.getQuery()); // Perform validation or manipulation on `doc` here next(); }); const Model = mongoose.model('Model', schema); - 2
Implement Validation Logic in Middleware
Add your validation logic within the `pre` middleware to ensure that the document meets the required criteria before proceeding with the update. This allows you to keep your validation centralized and maintainable.
javascriptif (!doc) { return next(new Error('Document not found')); // Handle document not found } if (!update.name) { return next(new Error('Name is required')); // Example validation } - 3
Test the Middleware Functionality
Create unit tests to ensure that the middleware behaves as expected. Confirm that the validation logic correctly prevents updates when the criteria are not met.
javascriptconst request = require('supertest'); const app = require('./app'); // Your Express app describe('PUT /model/:id', () => { it('should return 400 if name is missing', async () => { const response = await request(app) .put('/model/123') .send({}); expect(response.status).toBe(400); }); }); - 4
Update Documentation and Code Comments
Ensure that your code is well-documented, especially regarding the behavior of the `pre` middleware for `findOneAndUpdate` and `updateOne`. This will help future developers understand the design decisions and the need for separate handling.
javascript// This middleware handles validation for updates, ensuring the document is valid before proceeding.
Validation
To confirm the fix worked, run your API tests to ensure that updates are validated correctly and that invalid updates are rejected with appropriate error messages. Additionally, check that valid updates proceed as expected.
Sign in to verify this fix
Environment
Submitted by
Alex Chen
2450 rep