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 middleware no longer called #6914

Closed
lobermann opened this issue Aug 23, 2018 · 6 comments
Closed

pre remove middleware no longer called #6914

lobermann opened this issue Aug 23, 2018 · 6 comments

Comments

@lobermann
Copy link

Do you want to request a feature or report a bug?
Undocumented Behaviour, Possible Bug?

What is the current behavior?
Using following code from previous version with the latest version:

let user = await Models.user.findById(req.params.id)
...
await user.remove()

When using Object.remove() it also calls schema.pre('remove', function... . But now in the latest version when using remove it prints: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.. But with that the pre('remove') no longer gets called. I tried the deleteOne and the oder findByIdAndDelete() calls but the pre('remove') gets never called.

What is the expected behavior?
I can not find in the docs if the pre('remove') still exists and if what action actually invoked it.

Please mention your node.js, mongoose and MongoDB version.
node v9.5.0
mongoose 5.2.9
mongodb 3.6

@lineus
Copy link
Collaborator

lineus commented Aug 24, 2018

The following script shows that the remove hooks are still being called despite the deprecation warnings ( deprecation warnings covered in #6880 ):

6914.js

#!/usr/bin/env node
'use strict';

var preHookWasCalled = false;
var postHookWasCalled = false;

const assert = require('assert');
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true });
const conn = mongoose.connection;
const Schema = mongoose.Schema;

const schema = new Schema({
  name: String
});

schema.pre('remove', function() {
  preHookWasCalled = true;
});

schema.post('remove', function () {
  postHookWasCalled = true;
});

const Test = mongoose.model('test', schema);

const test = new Test({ name: 'one' });

async function run() {
  await conn.dropDatabase();
  await test.save();
  let doc = await Test.findOne();
  await doc.remove();
  let { length } = await Test.find();
  assert.strictEqual(mongoose.version, '5.2.9');
  assert.strictEqual(preHookWasCalled, true);
  assert.strictEqual(postHookWasCalled, true);
  assert.strictEqual(length, 0);
  console.log('all tests pass');
  return conn.close();
}

run();

Output:

issues: ./6914.js
(node:4593) DeprecationWarning: collection.find option [fields] is deprecated and will be removed in a later version.
(node:4593) DeprecationWarning: collection.find option [fields] is deprecated and will be removed in a later version.
(node:4593) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
all tests pass
issues:

The current docs still have the remove hook documented on the middleware page

Only calling .remove() on a document will fire remove hooks.
Calling Model.remove or Model.deleteMany or Model.deleteOne will not fire remove hooks.

@lineus lineus closed this as completed Aug 24, 2018
@lineus lineus reopened this Aug 24, 2018
@lineus
Copy link
Collaborator

lineus commented Aug 24, 2018

@lobermann can you provide a script that shows document.remove not firing the pre and post hooks?

@lobermann
Copy link
Author

No, you got me wrong here I think. Document.remove() calls the hooks, that is not the problem. The Problem is that Document.remove() prints out the deprecation warning, and none of the 3 suggestions it proposes call the hook to what I tested. And there is no indication in the documentation which ones do call the hooks.

I have it on remove now, but I want to do it already correct if possible, so that I do not have to change all the Document.remove() calls when I update later on.

@lobermann
Copy link
Author

Only calling .remove() on a document will fire remove hooks.
Calling Model.remove or Model.deleteMany or Model.deleteOne will not fire remove hooks.

I read the issue #6880 , so that is clear to me now.

But, if Document.remove() get's deprecated and removed at some point, what will be the new way of removing a document that will invoke the hooks?

@lineus
Copy link
Collaborator

lineus commented Aug 24, 2018

document.remove() has been updated in the master branch to call collection.deleteOne instead of collection.remove(). The hooks will still be called and no further deprecation warnings will come from calling document.remove(). The next release of mongoose will contain the fix for this 👍

@lineus lineus closed this as completed Aug 24, 2018
@lobermann
Copy link
Author

Awesome! Thank you very much for your assistance! Appreciate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants