Search code examples
mongodbmongoose-schema

Mongoose middleware is not being called for findByIdAndDelete


const mongoose = require('mongoose');
const { Schema } = mongoose;

main().catch(err => console.log(err));

async function main() {
  await mongoose.connect('mongodb://127.0.0.1:27017/relationDatabase');
}

const orderSchema = new Schema({
    item: String,
    price: Number
});

const Order = mongoose.model("Order", orderSchema);

const customerSchema = new Schema({
    name: String,
    orders: [
        {
            type: Schema.Types.ObjectId,
            ref: "Order"
        }
    ]
});

const Customer = mongoose.model("Customer", customerSchema);

customerSchema.pre('findOneAndDelete',async ()=>{
    console.log("POST MIDDLEWARE");
});

customerSchema.post("findOneAndDelete",  async ()=>{
    console.log("POST MIDDLEWARE");
});

async function deleteCustomer() {
    const deletedCustomer = await Customer.findByIdAndDelete("6644eb4bc7df9bee46d64981");
    console.log(deletedCustomer);
}

let addCustomer=async ()=>{
    let cust1=new Customer({
        name:"john snow",
    })


    let order1=await Order.findOne({item:"burger"});
    let order2=await Order.findOne({item:"pasta"});

    cust1.orders.push(order1);
    cust1.orders.push(order2);

    let res=await cust1.save();

    console.log(res);
} 

deleteCustomer();

tring to call findOneAndDelete MDW but its not able to print anything as it is not called I tried directly using findOneAndDelete but same result not calling MDW findOneAndDelete,i am expecting console.log("POST MIDDLEWARE") to be printed .


Solution

  • There are 2 issues in this case:

    a) Calling pre() or post() after compiling a model does not work in Mongoose in general, refer link 1 below. Therefore please change the order of statements as this:

    customerSchema.pre('findOneAndDelete',async ()=>{
        console.log("POST MIDDLEWARE");
    });
    
    customerSchema.post("findOneAndDelete",  async ()=>{
        console.log("POST MIDDLEWARE");
    });
    
    const Customer = mongoose.model("Customer", customerSchema);
    

    b) findByIdAndDelete does not have an equivalent middleware, write middleware on findOneAndDelete instead, refer link 2 below.

    Sample codes enclosed below.

    const mongoose = require('/usr/local/lib/node_modules/mongoose');
    const { Schema } = mongoose;
    
    run().catch((error) => console.log(error));
    
    async function run() {
    
      await mongoose.connect('mongodb://127.0.0.1:27017/test');
    
      const someSchema = new Schema({ key1: String });
      someSchema.pre('findOneAndDelete', async function () {
        console.log('findOneAdDelete PRE middleware');
      });
      someSchema.post('findOneAndDelete', async function () {
        console.log('findOneAdDelete POST middleware');
      });
    
      const SomeModel = mongoose.model('SomeModel', someSchema);
      SomeModel.deleteMany();
    
      await SomeModel.findOneAndDelete({});
      const someId = new mongoose.Types.ObjectId();
      await SomeModel.findByIdAndDelete(someId);
    }
    
    Output:
    findOneAdDelete PRE middleware
    findOneAdDelete POST middleware
    findOneAdDelete PRE middleware
    findOneAdDelete POST middleware
    

    Links:

    1. Define Middleware Before Compiling Models

    2. Mongoose pre middleware with findByIdAndDelete