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

mongodb find
mongodb find in array
mongodb array not empty
mongodb null or empty
mongodb check if value exists
mongodb check if field exists
mongodb aggregation match if field exists
mongodb check if document exists

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 });
}

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

Empty array is saved when a property references a schema · Issue , lookfirst opened this issue on Feb 5, 2013 · 39 comments. Closed Perhaps I should open a new issue for this to get noticed? — Creating a mongoose model containing array types return undefined for those in my docker container #​4534. The find method executes the callback function once for each index of the array until the callback returns a truthy value. If so, find immediately returns the value of that element. Otherwise, find returns undefined. callback is invoked for every index of the array, not just those with assigned values.


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

$exists, Array Query Operators $comment · Projection Operators When <boolean> is true, $exists matches the documents that contain the field, If <boolean> is false, the query returns only the documents that do not contain the field. [1] that contain the field a , including the document whose field a contains a null value: copy. To return all documents in a collection, omit this parameter or pass an empty document ({}). projection: document: Optional. Specifies the fields to return in the documents that match the query filter. To return all fields in the matching documents, omit this parameter. For details, see Projection.


you can use this :

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

cursor.toArray(), Returns: An array of documents. Consider the following example that applies toArray() to the cursor returned from the find  "Cannot read property 'createValueMap' of undefined" with mongo BaseEntity's create method #4367 Open AnatoleLucet opened this issue Jun 27, 2019 · 1 comment


$type, $comment · Projection Operators For documents where field is an array, $type returns documents in which at least 3.6 and later, the query find( {"data" : { $​type : "array" } } ) returns both documents. Undefined, 6, “undefined”, Deprecated. a non-existing object property movie.year; or a non-existing array element movies[3] are evaluated to undefined. The ECMAScript specification defines the type of undefined value: Undefined type is a type whose sole value is the undefined value. In this sense, typeof operator returns 'undefined' string for an undefined value:


updateOne(), Array Update Operators Specify an empty document { } to update the first document returned in the collection. The method returns a document that contains: you want to gather these into a comments field, like the second document. This query selects all documents in the inventory collection where the tags field holds either a string that starts with be or st or an array with at least one element that starts with be or st. See also


Array, Technologies Overview · HTML · CSS · JavaScript · Graphics · HTTP · APIs / DOM The array's object properties and list of array elements are separate, and the array's Using an invalid index number returns undefined . Array.prototype.​find(): Returns the found element in the array, if some element in  db.collection.insertOne() can be used inside multi-document transactions. The collection must already exist. An insert operation that would result in the creation of a new collection are not allowed in a transaction.