Collins Orlando
Collins Orlando

Reputation: 1681

MongoDB: Why is Array.find on comments (an array) property returning undefined?

Probably a silly issue, but why is the Array.find method not working as expected when working in this case? I'm trying to query a specific comment, which involves fetching the post document that has a comments property from the DB. It is from this comments array that I'd like to extract said comment object. For whatever reason, the code below doesn't work. Why?

Below are the code snippets

// Post document from which the comments are extracted
const post = await Post.findById(postId).populate({
  path: "comments",
  select: "addedBy id"
});

// Resulting post.comments array
[
  { "id": "5d9b137ff542a30f2c135556", "addedBy": "5b8528131719dc141cf95c99" },
  { "id": "5d9b0ba2f28afc5c3013d4df", "addedBy": "5b8528131719dc141cf95c99" },
  { "id": "5d9b0c26f28afc5c3013d4e0", "addedBy": "5b8528131719dc141cf95c99" }
];

// For instance if commentId is '5d9b137ff542a30f2c135556' 
// the resulting comment object should be {"id":"5d9b137ff542a30f2c135556","addedBy":"5b8528131719dc141cf95c99"}
// However, commentToDelete is undefined
const commentId = "5d9b137ff542a30f2c135556";

const commentToDelete = comments.find(comment => comment["id"] === commentId);

Edit: Here's the full deleteComment controller code

async function deleteComment(req, res, userId, postId, commentId) {
  const post = await Post.findById(postId).populate({
    path: 'comments',
    select: 'addedBy id',
  });

  const commentToDelete = post.comments.find(
    comment => comment['id'] === commentId
  );

  if (commentToDelete.addedBy !== userId) {
    return res
      .status(403)
      .json({ message: 'You are not allowed to delete this comment' });
  }

  await Comment.findByIdAndDelete(commentId);

  const updatedPost = await Post.findByIdAndUpdate(
    post.id,
    { $pull: { comments: { id: commentId } } },
    { new: true, safe: true, upsert: true }
  ).populate(populateFields);

  return res.status(200).json({ updatedPost });
}

Upvotes: 1

Views: 71

Answers (3)

qqilihq
qqilihq

Reputation: 11454

comment => comment['id'] === commentId

Your comment subdocument comes from MongoDB/Mongoose, so comment['id'] will likely be of type ObjectID, which is never equal a string. Explicitly call the toString() function (or use some other approach for transforming to a string) before comparing:

comment => comment['id'].toString() === commentId

Upvotes: 1

Karim Chaari
Karim Chaari

Reputation: 402

you can use this :

const result = comments.find(
  ({ id }) => id === commentId,
);
console.log(result)
// should return { id: '5d9b137ff542a30f2c135556', addedBy: '5b8528131719dc141cf95c99' }

Upvotes: 0

Dhananjai Pai
Dhananjai Pai

Reputation: 6015

works fine in the below snippet, copied from your post! I am assuming it is posts.comments in your case and not comments.find? Check for typos

const comments = [
  { "id": "5d9b137ff542a30f2c135556", "addedBy": "5b8528131719dc141cf95c99" },
  { "id": "5d9b0ba2f28afc5c3013d4df", "addedBy": "5b8528131719dc141cf95c99" },
  { "id": "5d9b0c26f28afc5c3013d4e0", "addedBy": "5b8528131719dc141cf95c99" }
];

// For instance if commentId is '5d9b137ff542a30f2c135556' 
// the resulting comment object should be {"id":"5d9b137ff542a30f2c135556","addedBy":"5b8528131719dc141cf95c99"}
const commentId = "5d9b137ff542a30f2c135556";

// However, commentToDelete is undefined
const commentToDelete = comments.find(comment => comment["id"] === commentId);

console.log(commentToDelete);

Upvotes: 0

Related Questions