OmarYehiaDev
OmarYehiaDev

Reputation: 183

Problem in deleting object using Node.JS, Mongoose, MongoDB, and Express

I have a collection called subcategories, another collection called categories the collection categories has a field called subcategroies. It's an array that has the ids of the subcategories from the subcategories collections..

I have an endpoint DELETE /categories/categoryId/subcategoires/subcategoryId

subcategories.delete('/:categoryId/subcategories/:subcategoryId', async (req, res) => {
  try {
    const category = await Category.findById(req.params.categoryId);
    if(!category) return res.status(404).send("Cateory is not found");
    category.subCategories.remove( req.params.subcategoryId );
    const subCategory = await SubCategory.findByIdAndRemove(req.params.subcategoryId);
    if(!subCategory) return res.status(404).send("Subcategory is not found");
    res.status(202).send("Subcategory is deleted successfully");
  } catch (error) {
    res.send(error.message);
  }
}

So I want to remove the id of the deleted subcategory from the array of subcategories in category model..

category.subCategories.remove( req.params.subcategoryId );

I tried this line of code as found above but it's not working using Mongoose, MongoDB, and Express.

Upvotes: 1

Views: 759

Answers (1)

Marek Piotrowski
Marek Piotrowski

Reputation: 3076

Here, reproduced it locally:

const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/test2345", {
    useNewUrlParser: true
});
const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));
db.once("open", async function() {


    await mongoose.connection.db.dropDatabase();
    // we're connected!

    console.log("Connected");

    const subcategoriesSchema = new mongoose.Schema({
        name: String
    });

    const categoriesSchema = new mongoose.Schema({
        name: String,
        subcategories: [{
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Subcategory' //Edit: I'd put the schema. Silly me.
        }]
    });

    const Subcategory = mongoose.model("Subcategory", subcategoriesSchema);
    const Category = mongoose.model("Category", categoriesSchema);

    const cat1 = new Subcategory({
        name: "Pop"
    });
    const cat2 = new Subcategory({
        name: "Rock"
    });

    await cat1.save();
    await cat2.save();

    const ubercat = new Category({
        name: "Music",
        subcategories: [cat1._id, cat2._id]
    });
    await ubercat.save();

    async function removeSubcategory(categoryId, subcategoryId) {
        try {
            const category = await Category.findById(categoryId);
            if (!category) {
                console.log("No such category");
                return null
            }
            category.subcategories.remove(subcategoryId);
            category.save();
            console.log(subcategoryId);
            const subCategory = await Subcategory.findByIdAndRemove(subcategoryId);
            if (!subCategory) {
                console.log("No such subcategory");
                return null
            }
            console.log("Subcategory is deleted successfully");
        } catch (error) {
            console.log(error.message);
        }
    }

    await Subcategory.find(function(err, subcats) {
        if (err) return console.error(err);
        console.log(subcats);
    });

    await Category.find(function(err, cats) {
        if (err) return console.error(err);
        console.log(cats);
    });

    await removeSubcategory(ubercat._id, ubercat.subcategories[0]._id);
    console.log("After modification.");
    await Category.find(function(err, cats) {
        if (err) return console.error(err);
        console.log(cats);
    });

});

The problem in your script is that after category.subCategories.remove( req.params.subcategoryId ); you are missing category.save();, so the transaction is not commited to the DB.

Output after adding save:

Connected
[ { _id: 5f439bf63224885dbc87e5cf, name: 'Pop', __v: 0 },
  { _id: 5f439bf63224885dbc87e5d0, name: 'Rock', __v: 0 } ]
[ { subcategories: [ 5f439bf63224885dbc87e5cf, 5f439bf63224885dbc87e5d0 ],
    _id: 5f439bf63224885dbc87e5d1,
    name: 'Music',
    __v: 0 } ]
5f439bf63224885dbc87e5cf
(node:23996) DeprecationWarning: Mongoose: `findOneAndUpdate()` and `findOneAndDelete()` without the `useFindAndModify` option set to false are deprecated. See: https://mongoosejs.com/docs/deprecations.html#findandmodify
Subcategory is deleted successfully
After modification.
[ { subcategories: [ 5f439bf63224885dbc87e5d0 ],
    _id: 5f439bf63224885dbc87e5d1,
    name: 'Music',
    __v: 1 } ]

Upvotes: 2

Related Questions