0

I have a comment update route that refers to the url /campgrounds/:id/comments/:comment_id and I use it in the app.js as app.use("/campgrounds/:id/comments", commentsRoutes);

The comments refers to a campground post. This is the Comment Update Route:

router.put("/:comment_id", function (req, res) {
    Comment.findByIdAndUpdate(req.params.comment_id, req.body.comment, {new: true})
        .exec(function(err, updatedComment){
            if (err) {
                res.redirect("back");
            } else {
                console.log("this is the updated comment" + updatedComment);
                res.redirect("/campgrounds/" + req.params.id);
            }
        });
});

I use mongoose to find a comment by url params id, look for the changes in comment and try to update it and redirect to /campgrounds/:id (the campgrounds show route)

I don't know why, but this code doesn't works: if I log the updatedComment I have:

this is the new comment 
{ author: { id: 5a5dc000af7fbb1138a27e33, username: 'patata' },
  _id: 5a5e0845f62da603900ab0d5,
  text: 'updated text field',
  __v: 0 }

the res.redirect works, but the page shows the old value of the comment, and if I log the campground in the campground show route, I have this output:

{ author: { id: 5a5dc000af7fbb1138a27e33, username: 'patata' },
  comments: 
   [ { author: [Object],
       _id: 5a5e0845f62da603900ab0d5,
       text: 'old text field',
       __v: 0 } ],
  _id: 5a5e083af62da603900ab0d4,
  name: 'Armando',
  image: 'https://i.pinimg.com/originals/2e/b7/e2/2eb7e206036f11c94ed0cac8fb1fc05e.jpg',
  description: 'lalala',
  __v: 1 }

Please note that the comment id is the same (5a5e0845f62da603900ab0d5). Even if I refresh the page, the comment is always the old one...

This is the Campground show route:

//SHOW
router.get('/:id', function (req, res) {
    //find correct campground ID
    Campground.findById(req.params.id).populate("comments").exec(function (err, foundCampground) {
        if (err) {
            console.log(err);
        } else {
            // render the show template
            console.log(foundCampground);
            res.render('campgrounds/show', {campground:foundCampground});
        }
    });
});

How can I solve this problem?

Thanks

EDIT: @AngelSalazar this is my campground model:

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

module.exports = mongoose.model("Campground", campgroundSchema);

and this is the Comment model:

var mongoose = require("mongoose");

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

module.exports = mongoose.model("Comment", commentSchema);

So I have to try to find the Campground Id, then find the campground comments and set the new value of the comment from the body req, then save Comment and Campground?

I Try this code:

router.put("/:comment_id", function (req, res) {
    Comment.findByIdAndUpdate(req.params.comment_id,
        {$set: {text: req.body.comment.text}},
        {new: true},
        function (err, updatedComment) {
            if (err) {
                res.redirect("back");
                console.log("error");
            } else {
                Campground.findByIdAndUpdate(req.params.id, 
                    {$set: {"comments.text": updatedComment.text}}, 
                    {new: true},
                    function (err, foundCampground) {
                        if (err) {
                            res.redirect("/campgrounds/" + req.params.id); // redirect to show page correctly
                            console.log("error"); // log error
                            console.log(foundCampground); // log undefined
                        } else {
                            res.redirect("/campgrounds/" + req.params.id);
                            console.log("ok");
                            console.log(foundCampground);
                        }
                    });
            }
        });
});

The stranger thing is that now the update is done, but the route redirecting to the campground show page works only if the error state is met! The console shows an error, but the campground is updated, I don't now why, but is pretty weird for me...

ufollettu
  • 822
  • 3
  • 19
  • 45
  • is comment in req.body.comment an object?, what you should pass is something like Comment.findByIdAndUpdate(req.params.comment_id, { $set : { text : req.body.comment } }, {new: true}) – AngelSalazar Jan 16 '18 at 20:35
  • Yes, is an Object, I try `Comment.findByIdAndUpdate(req.params.comment_id, { text : req.body.comment.text }, {new: true})` but does not update comment – ufollettu Jan 16 '18 at 20:43
  • the second parameter should be { $set : { text : req.body.comment.text } } – AngelSalazar Jan 16 '18 at 20:47
  • tried (see below), but still not working. If I get the edit page I have the new comment.text value in the correct field, but when I redirect to the show page something goes wrong – ufollettu Jan 16 '18 at 20:59
  • Can you show your models? I believe Comment is a subdocument of other document, if that is the case you first have to get the Other document, querying its comments, from it you should find the comment you want to update modify it and then save the Document (No the subdocument) – AngelSalazar Jan 17 '18 at 03:10
  • take a look to the following link https://stackoverflow.com/questions/26156687/mongoose-find-update-subdocument – AngelSalazar Jan 17 '18 at 03:15

2 Answers2

0

You must use $set to define what will be updated.

Please check mongoose docs on Documents page, Update item: http://mongoosejs.com/docs/documents.html

rossijonas
  • 183
  • 1
  • 10
0

@Mayank Yadav: I did not found a way to do that with mongoose 5.x, and I had to downgrade to 4.11.9 version. The code that works for me in this case is:

Comment Put Route

// Update for  "mongoose": "^4.11.9",
router.put("/:comment_id", function(req, res){
    Comment.findByIdAndUpdate(req.params.comment_id, req.body.comment, function(err, comment){
        if(err){
            console.log(err);
            res.render("edit");
        } else {
            res.redirect("/campgrounds/" + req.params.id);
        }
    });
});

However, please check the MongoDB compatibility in this page: http://mongoosejs.com/docs/compatibility.html, because maybe you have to change your model using usePushEach:

Comment Model

var mongoose = require("mongoose");

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

module.exports = mongoose.model("Comment", commentSchema);

Hope it helps. Bye

ufollettu
  • 822
  • 3
  • 19
  • 45