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;
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
.