Home > Back-end >  Mongoose pre updateOne hook is not invoked while doc is updated
Mongoose pre updateOne hook is not invoked while doc is updated

Time:09-23

I have this schema and fields like basicSalary can be edited by admin through dashboard UI, the pre save hook works fine to calculate fields, followed by pre updateOne hook to update the doc when it's edited by admin

const salariesSchema = mongoose.Schema({
  employeeId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "employee",
    required: true,
  },
  month: { type: String, required: true },
  year: { type: String, required: true },
  basicSalary: { type: Number, default: 0, required: true },
  accomodation: { type: Number, default: 0 },
  transportation: { type: Number, default: 0 },
  bonus: { type: Number, default: 0 },
  SSC: { type: Number, default: 0 },
  incomeTax: { type: Number, default: 0 },
  medicalInsurance: { type: Number, default: 0 },
  loan: { type: Number, default: 0, default: null },
  totalEarnings: { type: Number },
  totalDeductions: { type: Number },
  netSalary: { type: Number },
});
salariesSchema.pre("save", function (next) {
  this.SSC = this.basicSalary * 0.07;
  this.totalEarnings =
    this.basicSalary   this.accomodation   this.transportation   this.bonus;
  this.totalDeductions =
    this.incomeTax   this.medicalInsurance   this.loan   this.SSC;
  this.netSalary = this.totalEarnings - this.totalDeductions;
  next();
});

salariesSchema.pre("updateOne", function (next) {
  this.SSC = this.basicSalary * 0.07;
  this.totalEarnings =
    this.basicSalary   this.accomodation   this.transportation   this.bonus;
  this.totalDeductions =
    this.incomeTax   this.medicalInsurance   this.loan   this.SSC;
  this.netSalary = this.totalEarnings - this.totalDeductions;
  next();
});

routes > salary..js

const Salary = require("../models/Salary");

const editSalary = async (req, res) => {
  try {
    const salary = Salary.findById(req.body._id);
    await salary.updateOne({ $set: req.body });
    res.status(200).json("salary has been updated successfully");
  } catch (err) {
    console.log(err);
    res.status(400).json(err);
  }
};

if admin for example increased basicSalary by 50, totalEarningsand netSalary values should also be updated by 50 based on the calculations in pre updateOne hook, but that doesn't work, what's wrong here ?

CodePudding user response:

You should create separate pre hook for other types of queries. For example, you can add updateOne pre hook:

salariesSchema.pre("save", function (next) {
  this.SSC = this.basicSalary * 0.07;
  this.totalEarnings =
    this.basicSalary   this.accomodation   this.transportation   this.bonus;
  this.totalDeductions =
    this.incomeTax   this.medicalInsurance   this.loan   this.SSC;
  this.netSalary = this.totalEarnings - this.totalDeductions;
  next();
});

salariesSchema.pre('updateOne', function() {
  this.SSC = this.basicSalary * 0.07;
  this.totalEarnings =
    this.basicSalary   this.accomodation   this.transportation   this.bonus;
  this.totalDeductions =
    this.incomeTax   this.medicalInsurance   this.loan   this.SSC;
  this.netSalary = this.totalEarnings - this.totalDeductions;
  next();
});

CodePudding user response:

it turned out that i can't access fields directly by using this.fieldName, i solved it by using this.get("fieldName") converted into a number, and using this.set ( see documentation ) instead of return fieldName = expression

let me know if you have a better way to do it

salariesSchema.pre("updateOne", function (next) {
  this.set({ SSC: Number(this.get("basicSalary")) * 0.07 });
  this.set({
    totalDeductions:
      Number(this.get("incomeTax"))  
      Number(this.get("medicalInsurance"))  
      Number(this.get("loan"))  
      Number(this.get("SSC")),
  });

  this.set({
    totalEarnings:
      Number(this.get("basicSalary"))  
      Number(this.get("accomodation"))  
      Number(this.get("transportation"))  
      Number(this.get("bonus")),
  });

  this.set({
    netSalary:
      Number(this.get("totalEarnings")) - Number(this.get("totalDeductions")),
  });

  next();
});
  • Related