Unlocking the Power of Reusing Pre Middleware Functions in Mongoose

In order to reuse a pre-middleware function within another pre-middleware, I have extracted a function as shown below:

async function encryptPassword(next) {
    if (!this.isModified('password')) {
        return next();
    }
    this.password = await bcrypt.hash(this.password, 5);
    this.passwordChangedAt = new Date();
    next();
}

UserSchema.pre('save', encryptPassword);

UserSchema.pre("findOneAndUpdate", encryptPassword);

However, an error is occurring stating that the this.isModified function is not recognized. It appears that this may be referencing something other than intended. How can this issue be resolved?

Answer №1

After delving into these pre/post hooks using a debugger and the documentation, I made some interesting discoveries (applicable to both pre and post):

When using the save hook, the context of this is the document itself. This allows you to update its fields, call methods like isModified, and more. There should be no issues with this method.

On the other hand, when using the findOneAndUpdate hook, the context of this refers to a query rather than the document. The Query object does not have access to documents or their inherited methods (like isModified).

I verified this through debugging and can confirm that it aligns with the current documentation.

A comprehensive list of hooks can be found here: https://mongoosejs.com/docs/middleware.html#types-of-middleware

You will notice that only specific hooks allow for document modifications:

validate
save
remove
updateOne
deleteOne
init (note: init hooks are synchronous)

All other hooks do not permit this behavior, which appears to be intentional (https://github.com/Automattic/mongoose/issues/964).

To address any issues with findOneAndUpdate, it seems the most suitable approach is to rework it into separate queries using findOne and updateOne.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring various endpoints using firestore Cloud Function

I am in the process of creating a versatile Cloud Function that can be executed on various endpoints. This is how my original Cloud Function looks: const functions = require('firebase-functions') const admin = require('firebase-admin' ...

Tips on separating a function into two separate files in Node.js

Hey there! I am just starting to explore Node.js so bear with me if I make any mistakes. So, I have this file: exports.Client = function() { this.example = function(name, callback) { console.log(name); }; ...

The function of the 'Class' attribute is not functioning properly

I am currently working on a search field with a drop-down menu that determines the type of data being searched. This, in turn, dictates the input type for the search field. For example, if I am searching by "name" or "ID number", the input type is set to t ...

Identifying a Resizable Div that Preserves its Aspect Ratio During Resizing

Below is the HTML code snippet I'm working with: <div id="myid_templates_editor_text_1" class="myid_templates_editor_element myid_templates_editor_text ui-resizable ui-draggable" style="width: 126.79999999999998px; height: 110px; position: absolut ...

The dot notation in JSON syntax allows for easy access

Recently, I've been struggling with referencing a variable in JSON dot notation within my meteor application. It seems that when trying to access respJson.userlower.name, userlower is not being recognized as a valid variable. Is there a workaround for ...

Transferring `ngModel` from a nested component to its parent component

Is there a way to utilize [(ngModel)] within a child component? My goal is to break down a large and complex form into smaller, more manageable sections. I believe this approach will enhance the readability of my code. Unfortunately, the code I currently ...

What is the best way to transform my mongoose find request into the MongoDB aggregation framework?

I am looking to translate my current code into the mongodb aggregation framework. Here is the code that I need to convert into aggregation. const comments = await Comments.find({post:req.params.id}) .populate({ path:" ...

Using dataloader on ammap effectively involves importing the necessary data into the platform

I've been attempting to implement the dataloader feature on ammap without success. Here is my current approach: var birth_map = AmCharts.makeChart( "il_bazinda_dogum_say_dagilim", { "type": "map", "data": { ...

Access the data emitted by an event in Vue.js

Can someone help me with extracting the content of a $event.emit? I am facing an issue where the console.log inside the function displays the content, but once outside the function, it does not show the variable. mounted () { this.$events.on('emitE ...

HTML - implementing a login system without the use of PHP

While I am aware that the answer may lean towards being negative, I am currently in the process of developing a series of web pages for an IST assignment in Year 9. Unfortunately, the web page cannot be hosted and our assessor lacks the expertise to utiliz ...

ng-bind-html is having trouble parsing the HTML correctly and binding it

Here is the code for my controller: myApp.controller('actionEditController', ['$scope', '$stateParams', '$sce',function ($scope, $stateParams, $sce) { $scope.table="<p>OOPSY</p>"; $sc ...

What is the best way to include distinct text beneath each box within this slider or carousel?

Is there a way to add new text at the bottom of each box in this code? Visit CodePen I specifically want the new text to show underneath the boxes, not inside them. Each box should have different text associated with it. When you navigate using the left ...

Render just one pie chart using Highcharts.js manually

Is it possible to customize the colors of a single pie in a PieChart? In the documentation, I noticed that you can format the "dataLabels" by using a function. I would like to have similar control over customizing the color of a specific pie in a PieChart ...

Show various Bootstrap Alert Messages based on the type of error detected?

Trying to figure out how best to explain this, here it goes! I am working on a website and I want to incorporate alert messages. Check out some examples here. Depending on the form inputs, I need different alerts to be displayed. PHP will validate the in ...

A JavaScript Regex that eliminates all content outside specific HTML tags, including the tags themselves

Trying to parse a SOAP output using JS REGEX, even though it's not the ideal method. The format is as follows: *huge header* <NewDataSet> *content* </NewDataSet> *rest of footer* The goal is to remove everything outside the <NewDataSe ...

Locate and dismiss a toast message (Toastr)

I have a webpage where I can add multiple popup notifications called toasts dynamically using the toastr plugin found at https://github.com/CodeSeven/toastr. Each toast has an Ok link that, when clicked, should only close that specific toast and not all v ...

How can we achieve the reloading, refreshing, unbinding, destroying, enabling, and activating of a JavaScript/jQuery function?

Feeling a bit lost with my question title, let me explain the situation I'm in. Any assistance you can offer would be greatly appreciated. This is unfamiliar territory for me, which is why I haven't been able to find a solution through Google. ...

How can I eliminate the Origin header that jQuery adds to my Ajax requests?

As an example, consider the following Ajax request: $.post( 'http://example.com/script.pl', formdata, function ( data ) { // ... }); However, despite not being a cross-domain request, this request also contains an "Origin" header. What is ...

I keep getting an error message that says "The JSX element type does not have any construct or call signatures."

I am currently developing an application that takes user input through buttons and creates an array. However, when I attempt to display the array, I encounter a JSX element type error. import { Delete } from "lucide-react" export function Passwo ...

Expo (React Native) failure is causing issues in Jest due to a missing property

Issue with the test suite running: Encountered a TypeError: Cannot read property 'linkingUri' of undefined at Object. (node_modules/expo/src/Constants.js:18:29) at Object. (node_modules/expo/src/Logs.js:94:228) at Object. (node_mo ...