Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pre-remove hooks not called for subdocuments #9885

Closed
TimUnderhay opened this issue Feb 1, 2021 · 6 comments · Fixed by #9895 or #14732
Closed

Pre-remove hooks not called for subdocuments #9885

TimUnderhay opened this issue Feb 1, 2021 · 6 comments · Fixed by #9895 or #14732
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Milestone

Comments

@TimUnderhay
Copy link

TimUnderhay commented Feb 1, 2021

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
Pre-remove middleware is not called when removing an item from an array of subdocuments. According to #6224, this seemed to work with Mongoose <5.0.0. @vkarpov15 asked @georgehess to open a new issue on this in the same #6224, though it appears not to have happened, thus I'm running it up the flagpole.

This behaviour presents a problem for me because I need to know when a document is removed from an array, so that a corresponding cache entry can be deleted. Unfortunately, modifiedPaths doesn't provide enough context to tell me when something is removed, only that something happened. I can, of course, clear the cache entry manually from outside of my Mongoose code, but this seems like a less-than-elegant solution.

If the current behavior is a bug, please provide the steps to reproduce.

const mongoose = require('mongoose');

const SubSchema = mongoose.Schema({
  myValue: {
    type: String
  }
}, {});

SubSchema.pre('remove', async function() {
  console.log('Subdoc got removed!')
});



const Schema = mongoose.Schema({
  foo: {
    type: String,
    required: true
  },
  mySubdoc: {
    type: [SubSchema],
    required: true
  }
}, {minimize: false, collection: 'test'});

const Model = mongoose.model('TestModel', Schema);


const initMongoose = async () => {
  const mongooseUrl = `mongodb://user:pass@dbhost:27017/test`;
  try {
    await mongoose.connect(mongooseUrl, {
      useUnifiedTopology: true,
      useNewUrlParser: true,
      promiseLibrary: global.Promise,
      useFindAndModify: false
    });
  }
  catch (err) {
    console.error(err);
    process.exit(1);
  }
  console.log('Connected');
};


const test = async () => {
  await Model.deleteMany({}); // remove all existing documents
  const newModel = {
    foo: 'bar',
    mySubdoc: [{myValue: 'some value'}]
  };
  const document = await Model.create(newModel);
  console.log('Created document');
  console.log('document:', document);
  
  console.log('Removing subDocument');
  document.mySubdoc[0].remove();
  
  
  console.log('Saving document');
  await document.save().catch( (error) => {
    console.error(error);
    process.exit(1);
  });
  console.log('document:', document);

  console.log(`Notice that SubSchema.pre('remove') never ran`);
};



const main = async () => {
  await initMongoose();
  await test();
  process.exit(0);
};

main();

Output from the above is:

Connected
Created document
document: {
  _id: 601831bcddc22e01c640d6b6,
  foo: 'bar',
  mySubdoc: [ { _id: 601831bcddc22e01c640d6b7, myValue: 'some value' } ],
  __v: 0
}
Removing subDocument
Saving document
document: { _id: 601831bcddc22e01c640d6b6, foo: 'bar', mySubdoc: [], __v: 1 }
Notice that SubSchema.pre('remove') never ran

What is the expected behavior?
Pre-remove hooks should run when removing sub-documents.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
Mongoose 5.11.14
Node.js 15.5.1
MongoDB 4.4.1

@TimUnderhay TimUnderhay changed the title Pre-remove middleware not called for subdocuments Pre-remove hooks not called for subdocuments Feb 1, 2021
@IslandRhythms IslandRhythms added can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity. confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity. labels Feb 1, 2021
@vkarpov15 vkarpov15 added this to the 5.11.16 milestone Feb 5, 2021
@IslandRhythms IslandRhythms linked a pull request Feb 8, 2021 that will close this issue
@georgehess
Copy link

@TimUnderhay appreciate you opening this ticket. Did it ever work for you? I finally upgraded to v8.2 and still can't get pre/post middleware to fire for subdocuments when they are deleted.

@TimUnderhay
Copy link
Author

@georgehess IIRC the issue was resolved (though much time has passed so my memory is a bit fuzzy) but I’m no longer using Mongoose so I can’t comment on whether that’s still the case.

@vkarpov15
Copy link
Collaborator

@georgehess remove() is no longer supported as of Mongoose 7, so there's no more remove hooks either

@georgehess
Copy link

@vkarpov15 looks like the supplied alternative (deleteOne) works with pre middleware. Post middleware doesn’t work but I guess that’s a whole other topic.

@vkarpov15
Copy link
Collaborator

@georgehess can you please provide code samples that clarify what you mean by "Post middleware doesn’t work but I guess that’s a whole other topic."?

@georgehess
Copy link

@vkarpov15 here's a mongoose playground example of what I mean. The pre deleteOne middleware for subdocuments runs as expected but post deleteOne never does.

@vkarpov15 vkarpov15 reopened this Jul 6, 2024
@vkarpov15 vkarpov15 removed this from the 5.11.16 milestone Jul 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Projects
None yet
4 participants