MongoDB .deleteOne not working in Node.js
Asked Answered
O

3

6

So, i'm trying to delete a document when a button is pressed. The button code looks like this:

<form action="/patients/delete?_method=DELETE" method="POST">
    <input type="hidden" id="patientID" name="patientID" value=' _id: <%= patient._id%>'>
    <button type="submit" class="btn btn-primary">Delete this patient from the Database</button>
</form>

I've set up a route which looks like this:

router.delete('/delete', AuthControl.checkLoggedIn, patientsControl.patientDelete);

Which is calling this function in patientsControl:

    patientDelete = async (req, res) => {
    let DeleteParam = req.body.patientID;
    console.log(DeleteParam);
    let DeleteConfirm = await this.patientsModel.DeletePatient(DeleteParam);
    if (DeleteConfirm) {
        res.render('patients');
    } else {
        console.log("Error happening somewhere");
        }
    }

which is calling this function in the patientsModel:

async DeletePatient(DeleteParam) {
    return mongoose.connection.db.collection("PatientsDB").
    deleteOne({ _id : DeleteParam);
}

//EDIT: quickly fixed the above code, wasn't what I was running Which is returning true, as I'm not logging an error in patientDelete above.

the console.log(DeleteParam); is returning the id for the document i'm trying to delete, like this: 5f22dc43b1e72e9769263810

and the document im trying to delete looks like this:

_id : 5f22dc43b1e72e9769263810
fName : "s"
lName : "s"
diseases : "s"
prescriptions : []
inhousedoctor : "s"

What confuses me is, that if i set the button value to <%= patient.fName %> instead, it deletes perfectly. Can anyone please tell me what i'm doing wrong?

Edit: Ofc I mean that it works when i use fName instead like this:

        return mongoose.connection.db.collection("PatientsDB").
        deleteOne( {fName : DeleteParam});
    }```
Oviduct answered 30/7, 2020 at 15:27 Comment(3)
Yea, just saw - wasn't returning an error, and it still isn't working :/Oviduct
okay, for _id try this mongoose.Types.ObjectId(DeleteParam) for _id like deleteOne({ _id : mongoose.Types.ObjectId(DeleteParam)});Sibel
That one did it mate, thanks!Oviduct
G
7

The _id of the document is of type ObjectId but you are searching for a string, so no documents match.

If you use a Mongoose model, the type is converted automatically. But here you are not actually using Mongoose other than as a way to get the underlying MongoDB connection (mongoose.connection). So you are then working with pure MongoDB which does not do the conversion for you.

So you can either use the corresponding Mongoose model and write e.g. Patient.deleteOne({ _id: DeleteParam }) or just Patient.findByIdAndDelete(DeleteParam), or you can continue using MongoDB directly but explicitly convert the value to an ObjectId, using { _id: mongoose.Types.ObjectId(DeleteParam) }.

Graphomotor answered 30/7, 2020 at 15:37 Comment(2)
I should've mentioned that I'm running native mongodb inside the Mongoose connection as I'm having issues with the schemas. Isn't it possible to do this without having to define a schema, using just native mongo?Oviduct
Yes, I described it at the end of my answer. The key is to convert the ID that you search for to an ObjectId.Graphomotor
W
1

I'm not sure if this is a contributing factor, but your form is a POST method but your endpoint is a DELETE. Maybe try making both either POST or DELETE.

Willamina answered 30/7, 2020 at 15:37 Comment(1)
I'm using method-Override, hence the weirdness in the methods hahaOviduct
R
0

I came across this issue lately on [email protected] and it should be like this:

 let result = await collection.deleteOne({ _id: new ObjectId(id) } )

Be aware of the difference between Mongoose and the MongoDB package. I'm using:

const { MongoClient, ObjectId } = require("MongoDB");

and $ node -v:

v20.6.1
Radar answered 29/6 at 5:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.