1

--NodeJS, Mongoose, MongoDB, ExpressJS, EJS--

My website is, there is a login user, where they can submit "name" and "image" of what they want, then the author and other people can comment on that picture. On per each image, i added a function where i count the comments using the .length function which is counting the comments on the picture and projects the number of comments to my ejs file.

here is my schema:

var testSchema = new mongoose.Schema({
    name: String,
    image: String,
    author: {
        id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "Loginuser"
        },
            username: String
    },
    comments: [
        {
        type: mongoose.Schema.Types.ObjectId,
        ref: "Comment"
        }
    ]
});

var commentSchema = new mongoose.Schema ({
    author: {
        id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "Loginuser"
        },
        username: String
    },
    text: String,
    date: String
});

var loginSchema = new mongoose.Schema ({
    username: String,
    password: String
});


var TestData = mongoose.model("User", testSchema);
var Comment = mongoose.model("Comment", commentSchema);
var LoginUser = mongoose.model("Loginuser", loginSchema);

I have a function that deletes a comment on User,

app.delete("/index/:id/comments/:comment_id", function(req, res){
    Comment.findByIdAndRemove(req.params.comment_id, function(err){
        if(err) {
            console.log(err);
            res.redirect("/index/");
        } else {
            console.log("Comment successfully deleted!");
            res.redirect("back");
        }
    });
});

Here's some sample data from my mongoDB commentSchema

{ "_id" : ObjectId("57d316e506d8e9186c168a49"), 
  "text" : "hey baby! why cry?", "
__v" : 0, 
  "author" : { "id" : ObjectId("57d148acd0f11325b0dcd3e6"), 
  "username" :
  "nagy" }, 
  "date" : "9/10/2016 , 8:07 AM" }

{ "_id" : ObjectId("57d316f706d8e9186c168a4a"), 
  "text" : "don't you cry baby!",
"__v" : 0, 
  "author" : { "id" : ObjectId("57d095d727e6b619383a39d0"), 
  "username": "doge" }, 
  "date" : "9/10/2016 , 8:07 AM" }

{ "_id" : ObjectId("57d3170306d8e9186c168a4b"), 
  "text" : "wow so cute!!!!!!", "_
_v" : 0, 
 "author" : { "id" : ObjectId("57d095d727e6b619383a39d0"), 
 "username" : "doge" }, "date" : "9/10/2016 , 8:07 AM" }

and here's my data on testSchema

{ "_id" : ObjectId("57d316c506d8e9186c168a47"), 
      "name" : "Baby crying", 
      "image": "https://s-media-cache-ak0.pinimg.com/564x/d0/bb/ed/d0bbed614353534df9a3be0abe
    5f1d78.jpg", 
       "comments" : [ ObjectId("57d316e506d8e9186c168a49"), ObjectId("57d3
    16f706d8e9186c168a4a") ], "author" : { "id" : ObjectId("57d095d727e6b619383a39d0
    "), "username" : "doge" }, "__v" : 2 }

{ "_id" : ObjectId("57d316dc06d8e9186c168a48"), 
  "name" : "Maria?! OZawa?!", 
  "image" : "https://dncache-mauganscorp.netdna-ssl.com/thumbseg/1092/1092126-bigthumb
nail.jpg", 
  "comments" : [ ObjectId("57d3170306d8e9186c168a4b") ], "author" : { "
id" : ObjectId("57d148acd0f11325b0dcd3e6"), "username" : "nagy" }, "__v" : 1 }

as you can see, the objectId of comment on testSchema and commentSchema is the same. basically they're related.

It is working fine, it's deleting the comment. The problem here is, it is deleting only on the "Comment" model.

I want to delete that same comment also on "TestData" model, because everytime i delete a comment, the count of comments remains the same.

i want to delete that specific comment on both models.

I tried using this approach:

app.delete("/index/:id/comments/:comment_id", function(req, res){
        TestData.findByIdAndRemove(req.params.comment_id)function(err){
        if(err) {
            console.log(err);
            res.redirect("/index");
        } else {
            res.redirect("back");
        }
    });
});

but it isn't working.

Can you help me on what specific query should i use?

UPDATE: I added a pre middleware but still not working, maybe im doing it wrong. i've put the pre middleware above the "app.delete". is that correct?

commentSchema.pre('remove', function (next) {
  User.update(
    { comments: this }, 
    { $pull: { comments: this._id } }, 
    { multi: true }
  ).exec(next)
});

app.delete('/index/:id/comments/:comment_id', function (req, res) {
  Comment.findById(req.params.comment_id, function(comment){
        comment.remove();
        console.log("comment succesfully deleted!");
        res.redirect("back");
    });
  });

After reading throught the stackoverflow that has a similar problem to mine, i've tried this one too... a similar pre middleware but it uses the "update".

    commentSchema.pre('update', function (next) {
  this.model('User').update(
    { comments: this }, 
    { $pull: { comments: this._id } }, 
    { multi: true }
  ).exec(next)
});

app.delete('/index/:id/comments/:comment_id', function (req, res) {
  Comment.findById(req.params.comment_id, function(comment){
        comment.update();
        console.log("comment succesfully deleted!");
        res.redirect("back");
    });
  });

and yeah still not working :(

1 Answer 1

1

You need to remove the comment id from the array manually. The better way to do this is adding a remove middleware to your comment schema:

commentSchema.pre('remove', function (next) {
  User.update(
    { comments: this }, 
    { $pull: { comments: this._id } }, 
    { multi: true }
  ).exec(next)
})

But remove middlewares are only executed by calling doc.remove, and not Model.findByIdAndRemove. So you need to change a little your code (I'm using promises here for a better readability, but you can do this with callbacks):

app.delete('/index/:id/comments/:comment_id', function (req, res) {
  Comment.findById(req.params.comment_id)
    .then(function (comment) {
      return comment.remove() // doc.remove will trigger the remove middleware
    })
    .then(function () {
      console.log('Comment successfully deleted!')
      return res.redirect('back')
    })
    .catch(function (err) {
      console.log(err)
      res.redirect('/index')
    })
})
Sign up to request clarification or add additional context in comments.

5 Comments

i tried to paste this on the code but it's giving me an error of "Unexpected token . "
i edited your code to this.. commentSchema.pre('remove', function (next) { User.update( { comments: this }, { $pull: { comments: this._id } }, { multi: true } ).exec(next) }); app.delete('/index/:id/comments/:comment_id', function (req, res) { Comment.findById(req.params.comment_id, function(err){ if(err) { console.log(err); } else { return comment.remove(); console.log("comment succesfully deleted!"); res.redirect("back"); } }); }); the error is "comment" isnt define on "comment.remove()"
app.delete('/index/:id/comments/:comment_id', function (req, res) { Comment.findById(req.params.comment_id, function(err){ if(err) { console.log(err); } else { return comment.remove(); console.log("comment succesfully deleted!"); res.redirect("back"); } }); }); the "comment" isn't define on comment.remove().. Thank you. how can i fix it?
app.delete('/index/:id/comments/:comment_id', function (req, res) { Comment.findById(req.params.comment_id, function(comment){ comment.remove(); console.log("comment succesfully deleted!"); res.redirect("back"); }); }); i updated the code i forgot the function(comment). but now the error gives me " Cannot read property 'remove' of null"
Sorry for that. Model.findById could return a null value if the document wasn't found. You must verify if it exists before comment.remove(). It's simple as if (comment) { comment.remove() } else { // return a 404 error }

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.