3

I'm trying to delete all dependencies of a schema when a DELETE request is sent to my API. Deleting goes ok, but the remove middleware, which is supposed to clean the dependencies, seems like is not even getting called.

This is my Customer schema:

var mongoose = require("mongoose"),
Schema = mongoose.Schema,
passportLocalMongoose = require('passport-local-mongoose');

var Order = require('./order');
var Customer = new Schema({
    name: String,
    telephone: Number,
    address: String,
    email: String,
    seller: String
});

Customer.post('remove', function(next) {
    Order.remove({ customer: this._id }).exec();
    next();
});

Customer.plugin(passportLocalMongoose);

module.exports = mongoose.model("Customer", Customer);

And this is my customer route:

var express = require('express');
var router = express.Router();
var passport = require('passport');
var isAuthenticated = require('./isAuthenticated');
var Customer = require('../models/customer');
var Order = require('../models/order');

// (...)

router.delete('/:customer_id', function(req, res) {
    Customer.remove({ _id: req.params.customer_id }, function(err) {
        if (err)
            res.json({ SERVER_RESPONSE: 0, SERVER_MESSAGE: "Error deleting", ERR: err });
        else res.json({ SERVER_RESPONSE: 1, SERVER_MESSAGE: "Customer deleted" });
    });
});

// (...)

I did look this question and Mongoose Docs (Mongoose Middleware) but it's still unclear to me. I don't know what I'm missing or doing wrong.

Thanks in advance!

EDIT

This is my project's repository. Please, feel free to look into.

Community
  • 1
  • 1
alexhzr
  • 153
  • 1
  • 1
  • 12

2 Answers2

8

I finally found the solution to this. Middleware wasn't firing because you must use remove(), save(), etc on model instances, not the model itself.

Example:

Customer.remove({...}); won't work.

Customer.findOne({...}, function(err, customer) {
  customer.remove();
});

will work and will do whatever is in Customer.post('remove').

alexhzr
  • 153
  • 1
  • 1
  • 12
  • When I do this, it removes ALL the documents from the collection. In this case, the "Customer" collection. Any ideas? – Royston Yinkore Sep 02 '15 at 20:12
  • Isn't that what you want to? – alexhzr Sep 03 '15 at 11:56
  • No, its meant to remove only ONE instance of "Customer", hence the use of "findOne". But it deletes ALL customer documents on the collection – Royston Yinkore Sep 03 '15 at 15:31
  • Hmmm... Ok, I know what you mean. I was wrong with my last comment. If you do `Customer.findOne()` and use the right filter, it should return only one document, which would be the only one that matches your filter. Here -> https://github.com/alexhzr/BilltasticJS/blob/master/routes/customer.js#L90-L101 I'm filtering by some params, then, when ONE is found, the middleware is fired -> https://github.com/alexhzr/BilltasticJS/blob/master/models/Customer.js#L14-L16 – alexhzr Sep 04 '15 at 16:27
1

Seems like this is the part you're focusing on:

Customer.post('remove', function(next) {
    Order.remove({ customer: this._id }).exec();
    next();
});

What you're doing wrong here is that the post hook is not given any flow control, so the next parameter is not actually a function but the document itself.

Change it up to this and you should get what you want:

Customer.post('remove', function(doc) {
    Order.remove({ customer: doc._id }).exec();
});

From the docs:

post middleware are executed after the hooked method and all of its pre middleware have completed. post middleware do not directly receive flow control, e.g. no next or done callbacks are passed to it. post hooks are a way to register traditional event listeners for these methods.

Sven
  • 5,155
  • 29
  • 53
  • I've tried what you said but I still get no results... I've also added `console.log(doc);` to see if it reaches the function, but it didn't. – alexhzr May 15 '15 at 10:01
  • It's probably that the function does not execute at all. Make sure that you're actually deleting a customer in the `DELETE` request. What version of `mongoose` do you have? – Sven May 15 '15 at 10:07
  • I have Mongoose 4.0.2. The DELETE request goes all ok; customer is deleted, but middleware doesn't work. – alexhzr May 15 '15 at 10:21
  • Could you try with a `Schema.pre('remove', fn);` instead? That way we can rule out if the `post`-hook is broken in your version. According to the [History.md](https://github.com/Automattic/mongoose/blob/master/History.md) they fixed something with the `post` hook in 4.0.3 - although it wasn't clear what they fixed. `fixed; sync post hooks now properly called after function` – Sven May 15 '15 at 10:35
  • Sorry, I don't know what is `fn`. A function? – alexhzr May 15 '15 at 10:52
  • Yes... Basically what I want you to do is: `Customer.pre('remove', function (doc) { // Other stuff here });` – Sven May 15 '15 at 10:53
  • And is the function even being executed? `console.log('executed');` – Sven May 15 '15 at 11:01
  • Nope, no logs on console. This is the console output: [link](http://i.imgur.com/FNR9nyk.png) – alexhzr May 15 '15 at 11:09
  • Well something's clearly misconfigured. Mongoose acts like it's a schemaless collection without any methods for some reason... – Sven May 15 '15 at 11:15
  • Thank you very much for your time! I've added the link to my project, if it helps. – alexhzr May 15 '15 at 11:29