Home > Net >  Mongoose pre hook findOneAndUpdate to modify document before saving
Mongoose pre hook findOneAndUpdate to modify document before saving

Time:09-04

I am using the mongoose pre hook for findOneAndUpdate. I went through the documentation to understand better it's usage. I would like to update the password field before it saves to DB. However, I am not getting the disired result - nothing gets changed. What would be the right approach for using the findOneAndUpdate pre hook to modify a certain field in the doc?

Actual Document

{
  _id: new ObjectId("622457f5555562da89b7a1dd"),
  id: '5982ca552aeb2b12344eb6cd',
  name: 'Test User',
  configuration: [
    {
      email: '[email protected]',
      password: 'p@ssw0rd',
      _id: new ObjectId("9473l58f2ad34efb816963dd"),
    },
    {
      email: '[email protected]',
      password: 'trUstN0oNe',
      _id: new ObjectId("8674884cec1877c59c8838e0")
    }
  ],
  __v: 0
}

Desired Document

{
  _id: new ObjectId("622457f5555562da89b7a1dd"),
  id: '5982ca552aeb2b12344eb6cd',
  name: 'Test User',
  configuration: [
    {
      email: '[email protected]',
      password: '0f359740bd1cda994f8b55330c86d845',
      _id: new ObjectId("9473l58f2ad34efb816963dd"),
    },
    {
      email: '[email protected]',
      password: '3dba7872281dfe3900672545356943ce',
      _id: new ObjectId("8674884cec1877c59c8838e0")
    }
  ],
  __v: 0
}

Code:

const UserSchema = new Schema({
   id: {
       type: String,
       required: [true, "'id' value is required"]
   },
   name: {
       type: String,
       required: [true, "'name' value is required"]
   },
   configuration: [ConfigModel.schema]
});

const ConfigSchema = new Schema({
   email: {
       type: String,
       required: [true, "Email is required"]
   },
   password: {
       type: String,
       required: [true, "Password is required"]
   }
});


UserSchema.pre('findOneAndUpdate', async function(next) {
   const docToUpdate = await this.model.findOne(this.getQuery());

   docToUpdate.botconfiguration.forEach((item,i) => {
      docToUpdate.configuration[i].password = md5(item.password);
   });
   return next();
});

CodePudding user response:

in userModel you read configuration from ConfigModel so you have to modify the config model not user model it just read and populate the data from config model.

CodePudding user response:

You are missing the .save() document command after changing the information inside the document, because you are only using findOne

   const docToUpdate = await this.model.findOne(this.getQuery());

   docToUpdate.botconfiguration.forEach((item,i) => {
      docToUpdate.configuration[i].password = md5(item.password);
   });
   await docToUpdate.save() // <---- this line

You dont need the updateMany() here because the ConfigSchema is nested inside the user collection

  • Related