I have just started learning the MERN stack and I am having trouble updating a text within a model with Express/Node. I tried to look for help and accessed
CodePudding user response:
You should update the cat instance once the comment has been fetched.
Try to change your code like this (using async wait
):
const updateComment = async (req, res) => {
// if there is no req.body, return error
if (!req.body) {
return res.status(400).json({
success: false,
error: 'You must provide a body to update',
});
}
try {
// req.body exists, so find the comment by id and then update
const comment = await Comment.findById(req.params.id);
if (!comment) {
return res.status(404).json({
err,
message: 'Comment not found!',
});
}
// update the comment details
comment.text = req.body.text;
// save the updated comment
await comment.save();
// now update the comment entry for the cat too
const cat = await Cat.findById(comment.cat_id);
const otherCatComments = cat.comments.filter((c) => c._id !== comment._id);
cat.comments = [...otherCatComments, comment];
await cat.save();
res.status(200).json({
success: true,
id: comment._id,
message: 'Comment updated!',
});
} catch (err) {
res.status(404).json({
error,
message: 'Comment not updated!',
});
}
};
CodePudding user response:
Luca, thank you! That was extremely helpful and I can see the appended comment added to the cats comment array. Now the only thing is the cats.comment.filter isn’t quite working as intended, as the otherCatsComments still includes all the comments. I had to do a little digging in the code and I managed to console log the id, which returns “_id: new ObjectId("617d57719e815e39f6049452"),” I tried changing it to
const otherCatComments = cat.comments.filter((c) => c._id !== `new ObjectId("${comment._id}")`);
const otherCatComments = cat.comments.filter((c) => c._id !== ` new ObjectId("${comment._id}")`);
const otherCatComments = cat.comments.filter((c) => c._id !== `ObjectId("${comment._id}")`);
But they all don’t seem to work, so I had to do a deep de-bugging and turns out my code is off for some things! I’ll just add them here in case anyone bumps into this issue in the future. First off, my comment id was different from the comment id within my cats model. For reference, here is my create comment model (I modified it to use the async/await try/catch block as recommended by Luca:
const createComment = async (req, res) => {
// if there is no req.body, return error
if (!req.body) {
return res.status(400).json({
success: false,
error: "You must provide a comment",
});
}
try {
// req.body exists, so make a new comment
const comment = new Comment(req.body);
await comment.save();
// now add comment to cat
Cat.findById(req.params.id, (err, foundCat) => {
// Append the comment to the cat
foundCat.comments.push(comment);
foundCat.save();
});
// somehow, if the new comment doesn't exist, return error
if (!comment) {
return res.status(400).json({ success: false, error: err });
}
// success!
res.status(201).json({
success: true,
id: comment._id,
message: "Comment created!",
});
} catch (err) {
return res.status(400).json({
err,
message: "Comment not created!",
});
}
};
Note the part where I add the comments in the cat: At first it was
foundCat.comments.push(req.body);
but this would generate a comment id in the cat that would be different from the comment id in the comment. so req.body is changed to comment.
Once that was fixed, I tried the original code by Luca, but it still didn’t work. My workaround was to not use the filter, and just delete the old comment and then add in the new comment. Code here:
const updateComment = async (req, res) => {
// if there is no req.body, return error
if (!req.body) {
return res.status(400).json({
success: false,
error: "You must provide a body to update",
});
}
try {
// req.body exists, so find the comment by id and then update
const comment = await Comment.findById(req.params.id);
if (!comment) {
return res.status(404).json({
err,
message: "Comment not found!",
});
}
// update the comment details
comment.text = req.body.text;
// save the updated comment
await comment.save();
// now update the comment entry for the cat too
const cat = await Cat.findById(comment.cat_id);
// remove the old, non-updated comment first
cat.comments.id(comment._id).remove();
// now add in the updated comment
cat.comments.push(comment);
await cat.save();
res.status(200).json({
success: true,
id: comment._id,
message: "Comment updated!",
});
} catch (err) {
res.status(404).json({
error,
message: "Comment not updated!",
});
}
};