Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.93k stars 3.84k forks source link

this doesn't print anything in deleteOne hook #8995

Closed amolsr closed 4 years ago

amolsr commented 4 years ago

Node : 10.20.1 Mongoose: 5.9.13 MongoAtlas

StudentSchema.pre('deleteOne', { document: false, query: true }, (next) => {
    var student = this;
    console.log(student)
    User.deleteOne({
        uname: student.rollNo
    }).then((result) => {
        //console.log(result)
        if (result.deletedCount > 0) {
            next();
        } else {
            console.log("Failed to delete user corresponding to student")
            next();
        }
    })
});

exports.deleteStudent = (req, res, next) => {
    const { rollNo } = req.params;
    Student.deleteOne({ rollNo: rollNo }).then(result => {
        if (result.deletedCount > 0) {
            req.rollNo = rollNo;
            next()
        } else {
            res.sendStatus(304);
        }
    })
};

Here Student is Model. this should not print empty json object.

amolsr commented 4 years ago
const mongoose = require('mongoose');

mongoose.connect('<DB-URL-HERE>', {
    useUnifiedTopology: true,
    useNewUrlParser: true,
    useFindAndModify: false
}).then(() => console.log('MongoDB Connected..')).catch(err => console.log(err));

const testSchema = new mongoose.Schema({
    name: {
        type: String
    },
    stdNo: {
        type: Number
    }
});

testSchema.pre('deleteOne', { document: false, query: true }, (next) => {
    var test = this;
    console.log(test)
    next()
});

const Test = mongoose.model('Test', testSchema);

async function main() {
    await Test.create({ name: "test", stdNo: 1602713103 })
        .then(result => console.log("Save Success "))
        .catch(err => console.log(err))
    await Test.deleteOne({ stdNo: 1602713103 })
        .then(result => console.log("Delete Success "))
        .catch(err => console.log(err))
    process.exit(1)
}

main()
AbdelrahmanHafez commented 4 years ago

Arrow functions have lexical `this`, use a regular function instead for the pre-hook handler.

8995.js

'use strict';
const mongoose = require('mongoose');
const assert = require('assert');

run().catch(console.error);

async function run () {
  await mongoose.connect('mongodb://localhost:27017/test', {
    useNewUrlParser: true,
    useUnifiedTopology: true
  });

  await mongoose.connection.dropDatabase();

  const testSchema = new mongoose.Schema({
    stdNo: { type: Number }
  });

  let filterFromHook;
  testSchema.pre('deleteOne', { document: false, query: true }, function () {
    filterFromHook = this.getFilter();
  });

  const Test = mongoose.model('Test', testSchema);

  await Test.deleteOne({ stdNo: 1602713103 });

  assert.ok(filterFromHook.stdNo === 1602713103);
  console.log('All assertions passed.');
}

Output

All assertions passed.