0

How do i perform a soft delete using nodejs on mongodb

for example using this code, can it be modified to do a soft delete instead or is there another way?

Controllers/ category.js

exports.remove = (req, res) => {
    const category = req.category;
    category.remove((error, data) => {
        if (error) {
            return res.status(400).json({
                error: errorHandler(error)
            });
        }
        res.json({
            message: "Category deleted"
        });
    });
};

routes/category.js

const express = require("express");
const router = express.Router();

const { create, categoryById, read, update, remove, list } = require("../controllers/category");
const { requireSignin, isAuth, isAdmin } = require("../controllers/auth");
const { userById } = require("../controllers/user");

router.get("/category/:categoryId", read);
router.post("/category/create/:userId", requireSignin, isAuth, isAdmin, create);
router.put("/category/:categoryId/:userId", requireSignin, isAuth, isAdmin, update);
router.delete("/category/:categoryId/:userId", requireSignin, isAuth, isAdmin, remove);
router.post("/categories", list);

router.param("categoryId", categoryById);
router.param("userId", userById);

module.exports = router;

models/category.js

const mongoose = require("mongoose");

const categorySchema = new mongoose.Schema(
    {
        name: {
            type: String,
            trim: true,
            required: true,
            maxlength: 32
        }
    },
    { timestamps: true }
);

module.exports = mongoose.model("Category", categorySchema);
8
  • Please tell what is schema of category? Commented Nov 3, 2019 at 9:28
  • What does a "soft delete" mean to you? ( Don't presume this is a universal term ). Please explain what you are expecting with specific examples. Show a small sample of documents, an operation and what you expect to happen to the data as a result of that operation. Your current question really does not explain much with the code provided. We can presume that req.category has been filled with the current mongoose model, or possibly a pre-prepared query. But given no code that shows any interaction with either :categoryId or :userId from the route, it's just *not very clear. Commented Nov 3, 2019 at 9:35
  • Soft delete as in the data is not deleted from the db. The data is still there but for the user it shows that the "item" or category is deleted. Commented Nov 3, 2019 at 10:02
  • @Omar req.category is not obvious parameter. is it mongoose model? or is it model instance (result of querying db)? Commented Nov 3, 2019 at 10:09
  • i added the models/category.js code Commented Nov 3, 2019 at 10:49

2 Answers 2

1

I'm not sure req.category is instance of model or model itself.

So in my answer below I assume that somehow You've got instance of model and injected it as req.category

1) Add deleted field to schemas where You want to have soft delete:

const mongoose = require("mongoose");
const {Schema} = mongoose;

const categorySchema = new Schema(
    {
        name: {
          type: Schema.Types.String,
          trim: true,
          required: true,
          maxlength: 32
        },

        // deleted flag for soft delete feature
        deleted: {
          type: Schema.Types.Boolean,
          index: true,
          default: false
        }
    },
    { timestamps: true }
);

module.exports = mongoose.model("Category", categorySchema);

2) Change delete procedure:

module.exports.remove = async (req, res) => {
  try {
    const category = req.category; // if it's an instance of model
    // or if it's mongoose model comment line above
    // const category = await req.category.findOne({
    //                                     _id: req.params.categoryId,
    //                                     deleted: false
    //                                   });

    if (!category || category.deleted === true) {
      return res.status(404).json({
        error: 'Requested category does not exist'
      });
    }

    category.deleted = true;
    await category.save();

    res.status(200).json({
      message: "Category deleted"
    });
  }
  catch (error) {
    res.status(400).json({
      error: errorHandler(error)
    });
  }
};

3) Change category read route: /category/:categoryId handler:

module.exports.read = async (req, res) => {
  try {
    const category = req.category; // if it's an instance of model
    // or if it's mongoose model comment line above
    // const category = await req.category.findOne({
    //                                     _id: req.params.categoryId,
    //                                     deleted: false
    //                                   });

    if (!category || category.deleted === true) {
      return res.status(404).json({
        error: 'Requested category does not exist'
      });
    }
    res.status(200).json(category);
  }
  catch (error) {
    res.status(400).json({
      error: errorHandler(error)
    });
  }
};

4) Change listing procedure:

module.exports.list = async (req, res) => {
  try {
    const categories = await req.category.find({deleted: false});
    res.status(200).json({categories});
  }
  catch (error) {
    res.status(400).json({
      error: errorHandler(error)
    });
  }
};
Sign up to request clarification or add additional context in comments.

3 Comments

Listing procedure didn't work. Returned an error, but when i ran my listing code it worked any ideas why?
@Omar fixed listing code I forgot to put await before req.category.find
@Omar keep in mind to change Schema according above code
0

Step 1: Add a new field in your Schema "Deleted" with type Boolean and Default value 'false'

deleted: { type: Boolean, default: false }

Step 2

Change Delete Process To:
router.delete('/:id', verifyTokenAndAuthorization, async (req, res) => {
  try {
    await User.findByIdAndUpdate(req.params.id, { deleted: true }); <= change delete status to 'true'
    res.status(200).json('user Deleted');
  } catch (error) {
    res.status(500).json(error)
  }
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.