Mr. B.
Mr. B.

Reputation: 8697

Mongoose: remove() returns true for already deleted items

my code below returns "User deleted" even if the user was already deleted. I'd prefer to throw a 404 in this case, but I'd like to query the DB as less as possible.

Is there a way to get the userNotFound (see below) without manually checking if the user existed before deletion? Maybe I missed a feature of remove() or an alternative function.

var itemId = 123;
Item.remove({id: itemId}, function(err) {
    if (err) {
        return res.json({success: false, msg: 'Cannot remove item'});
    }

    // !!!
    if (userNotFound) {
        return res.status(404).json({success: false, msg: 'User not found'});
    }  
    // /!!!


    res.json({success: true, msg: 'User deleted.'});
});

Thanks in advance!

Upvotes: 6

Views: 11035

Answers (2)

chridam
chridam

Reputation: 103365

The problem with the above approach is that userNotFound will always be undefined since you haven't defined it in the callback arguments. Better to use the findOneAndRemove() function so that you can return the document removed if found:

var itemId = 123;
Item.findOneAndRemove({ id: itemId }) 
    .exec(function(err, item) {
        if (err) {
            return res.json({success: false, msg: 'Cannot remove item'});
        }       
        if (!item) {
            return res.status(404).json({success: false, msg: 'User not found'});
        }  
        res.json({success: true, msg: 'User deleted.'});
    });

Upvotes: 12

Soubhik Mondal
Soubhik Mondal

Reputation: 2666

Mongoose's Query#remove accepts a callback with 2 parameters:

  1. error
  2. writeOpResult

If you check the writeOpResult object, you should easily be able to tell whether deletion occurred or not.

It should contain a field called nRemoved. If it is 0 then no document was deleted, otherwise if it is a number then that many documents have been deleted. Similarly it has a field called nMatched which tells you how many documents matched your query.

So for your case it becomes like this:

var itemId = 123;

Item.remove({id: itemId}, function(error, writeOpResult) {

    if (error) {
        return res.json({success: false, msg: 'Cannot remove item'});
    }

    if (writeOpResult.nMatched === 0) {
        return res.status(404).json({success: false, msg: 'User not found'});
    }

    res.json({success: true, msg: 'User deleted.'});
});

Upvotes: 4

Related Questions