skip to Main Content

I did the function in the controller correctly (as I think), but I could not delete the comment even though the postman returns the response “Comment deleted successfully!.”

When I go to the database, I find that the comment exists in the database and has not been deleted.

I want to know what is wrong with the code. It makes the deletion process not done as it should be.

comment route

router.delete("/:id/comment/:cid", protectRoute, deleteComment);

controller

const deleteComment = async(req, res) => {
try {
    const post = await Post.findById(req.params.id);

    const comment = post.comments.find(
        (comment) => comment._id.toString() === req.params.cid.toString()
    );

    if(!comment){
        return res.status(404).json({ error: "Comment not found!" });
    }

    if(comment.userId.toString() !== req.user._id.toString()){
        return res.status(401).json({ error: "Unauthorized to delete comment" });
    }

    if (comment.userId.toString() === req.user._id.toString()) {
        post.comments = post.comments.filter(
            ({ id }) => id !== req.params.cid
        );
    }
        await post.save();
    
        return res.status(200).json({ message: "Comment deleted successfully!" });
} catch (err) {
    res.status(500).json({ error: err.message });
}

};

my Post Model

import mongoose from "mongoose";
const ObjectId = mongoose.Types.ObjectId;

const postSchema = mongoose.Schema({
    postedBy: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        required: true
    },
    text: {
        type: String,
        maxLength: 500
    },
    img: {
        type: String,
    },
    video: {
        type: String,
        ref: "Upload"
    },
    likes: [{
        // array of user id's
        type: mongoose.Schema.Types.ObjectId,
        ref: "User",
        default: []
    }],
    saves: [{
        // array of user id's
        type: mongoose.Schema.Types.ObjectId,
        ref: "User",
        default: []
    }],
    comments: [
        {
            id: {
                type: ObjectId,
            },
            userId: {
                type: mongoose.Schema.Types.ObjectId,
                ref: "User",
                required: true
            },
            text: {
                type: String,
                required: true
            },
            likes: [{
                // array of user id's
                type: mongoose.Schema.Types.ObjectId,
                ref: "User",
                default: []
            }],
            userProfilePic: {
                type: String,
            },
            username: {
                type: String
            },
            date: {
                type: Date,
                default: Date.now()
            },
            replies: [{
                id: {
                    type: ObjectId,
                },
                userId: {
                    type: mongoose.Schema.Types.ObjectId,
                    ref: "User",
                    required: true
                },
                text: {
                    type: String,
                    required: true
                },
                userProfilePic: {
                    type: String,
                },
                username: {
                    type: String
                },
                date: {
                    type: Date,
                    default: Date.now()
                }
            }]
        }
    ]
}, {timestamps: true}
)

const Post = mongoose.model('Post', postSchema);

export default Post;

3

Answers


  1. You are using id in the filter function, but the actual property name in your comments array is _id. Additionally, it seems like you are comparing the IDs using strict equality (===) which may not work as expected since one is an ObjectId and the other is a string, try this code:-

    const deleteComment = async (req, res) => {
        try {
            const post = await Post.findById(req.params.id);
    
            const commentIndex = post.comments.findIndex(
                (comment) => comment._id.toString() === req.params.cid.toString()
            );
    
            if (commentIndex === -1) {
                return res.status(404).json({ error: "Comment not found!" });
            }
    
            if (post.comments[commentIndex].userId.toString() !== req.user._id.toString()) {
                return res.status(401).json({ error: "Unauthorized to delete comment" });
            }
    
            post.comments.splice(commentIndex, 1); // Remove the comment at commentIndex
            await post.save();
    
            return res.status(200).json({ message: "Comment deleted successfully!" });
        } catch (err) {
            res.status(500).json({ error: err.message });
        }
    };
    
    Login or Signup to reply.
  2. This is a common operation and is typically done with a simple findOneAndUpdate like so:

    const deleteComment = async(req, res) => {
       try{
           const post = await Post.findOneAndUpdate(
               {
                   _id: req.params.id, //< Match the Post._id
                   comments: { //< Must also match comments._id and comments.userId 
                       $elemMatch: {
                           _id: req.params.cid,
                           userId: req.user._id
                       }
                   }
               },
               {
                   $pull: {
                       'comments': {_id: req.params.cid}, //< Remove the comment from array
                   }
               },
               { new : true } //< Return the updated document after the comment removed
           );
           if(!post){ //< Will return null of no document matches
               return res.status(400).json({
                   error: "Comment not found!"
               });
           }
           return res.status(200).json({
               message: "Comment deleted successfully!"
           });
       } catch(err){
           console.log(err);
           res.status(500).json({
               error: err.message
           });
       }
    }
    

    Edit: Just noticed you are doing a check for userId too so you will need to use $elemMatch.

    Login or Signup to reply.
  3. @khayal As follow your approach, a slight change is needed.

    Here is the part of code should be replaced before await post.save(); line :

    if (comment.userId.toString() === req.user._id.toString()) {
        post.comments = post.comments.filter(
            (comment) => comment._id.toString() !== req.params.cid.toString()
        );
    }
    

    Hope to be helpful for your understanding.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search