I tried researching for the cause of this problem; it is most likely a misunderstanding on my part of the way Mongoose works. I was experimenting with creating a CRUD backend in REST style. GET, PUT, POST all seem to work. However, I'm a bit at a loss with a problem with the DELETE verb.
I entered some fake data into mongo with Postman and all went well. So I copied the _id field of one my records and tried to DELETE. When I sent the DELETE request, the success message came through and the record was indeed removed from mongo. However, after deleting other records, I decided to try deleting a record with an _id of a document I had already deleted.
I sent a DELETE request to 'api/brothers/57280602953cff031f21ad9c'
Turns out NodeJS crashes!
Here's the relevant server code:
// DELETE a brother by id
app.delete('/api/brothers/:id', function(req, res) {
Brother.findById(req.params.id, function(err, brother) {
if (err) {
// error finding brother
res.json(err);
} else {
// remove record
brother.remove(function(err, brother) {
if (err) {
// error removing!
res.send(err);
} else {
// successful DELETE!
res.json({
message : "successfully deleted",
brother : brother
});
}
});
}
});
});
Nodejs crashed and my console window returned the following:
TypeError: Cannot read property 'remove' of null
[nodemon] app crashed - waiting for file changes before starting...
To my understanding, an error was not thrown because, had it been thrown, my if
statement would have executed and returned the error to the user. If I enter a bogus id in the url then I get back an error, but if I paste in an _id of a record I already deleted, an error is NOT thrown, and execution moves on to the else
block, and goes ahead removing a document that doesn't exist. Not even the .remove()
seems to catch the error... the server just crashes.
So... my question is why? Does it have to do with Mongo casting the _id
? Why isn't an error thrown? Why does the server crash.
If I modify the if
statement to not only catch for an error, but to also check for the existence of a brother
returned from the findById()
function, the error is returned to the user and the disaster is averted:
if (err || !brother) {
// THIS WORKS
res.json(brother);
} else { ...
Again... why? Why if the brother
obj is null does Mongoose even attempt to delete the document? And why does the server crash?
// I am using Express 4.13.4 and Mongoose 4.4.12
Thank you for your help, and pardon any novice ignorance.
What you got is a Javascript error not a Mongoose one, you tried to call a method on null
. foo = null; foo.bar();
yields the same error.
Finding 0 document is not an error, the action of finding was carried out but 0 thing was found.
Mongoose has an helper function, findOneAndRemove, you should use it, less code to write, less headaches:
app.delete('/api/brothers/:id', function(req, res) {
Brother.findOneAndRemove({ _id: req.params.id }, function(err, brother, res) {
});
});
err
is thrown in case of events like, unable to connect to database, invalid authentication, etc. But for queries it does throw any error as long as query is correct. In your case of query returns 0
rows it will simply call your callback with null
, so you might want to put a check before using brother
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With