Ticket: AddComment not working in the UI (server error 500)

Greetings!

I was reading a lot in the forum about the following problem i not find the correct answer yet. Could you please give me some help?

The console give back the following error when trying to add a new comment form the UI as a loged in user.

Screenshot from 2021-06-18 11-31-47

When i submit a new comment I also noticed in the compass there will no new comment.

The advice was be sure about the correct sorting of the comments in the getMovieByID(id) function.
(My unit test pass)
Is it possible my code somewhere wrong?

  static async getMovieByID(id) {
try {
  /**
  Ticket: Get Comments

  Given a movie ID, build an Aggregation Pipeline to retrieve the comments
  matching that movie's ID.

  The $match stage is already completed. You will need to add a $lookup
  stage that searches the `comments` collection for the correct comments.
  */

  // TODO Ticket: Get Comments
  // Implement the required pipeline.
  const pipeline = [
    {
      '$match': {
        '_id': ObjectId(id)
      }
    },
    {
      '$lookup': {
        'from': 'comments', 
        'let': {
          'id': '$_id'
        }, 
        'pipeline': [
          {

            '$match': {
              '$expr': {
                '$eq': [
                  '$movie_id', '$$id'
                ]
              }
            }
          },
          {
            '$sort': {
              'date': -1
            }
          }
        ], 
        'as': 'comments'
      }
    }
  ]
  return await movies.aggregate(pipeline).next()
} catch (e) {
  /**
  Ticket: Error Handling

  Handle the error that occurs whennpm test -t error-handling an invalid ID is passed to this method.
  When this specific error is thrown, the method should return `null`.
  */

  // TODO Ticket: Error Handling
  // Catch the InvalidId error by string matching, and then handle it.
  console.error(`Something went wronpm test -t error-handlingng in getMovieByID: ${e}`)
  if (e != null){
    return null
  }
  //expected(e).toBeNull("err")
  //expected(e.errmsg).toContain("E1100 duplicate key error collection")
  throw e
}
  }
}

I also copy my AddComment / updateComment / deleteComment methods which also passed with the unit test.`

static async addComment(movieId, user, comment, date) {
try {
  // TODO Ticket: Create/Update Comments
  // Construct the comment document to be inserted into MongoDB.
  const commentDoc = {
     name: user.name,
     email: user.email,
     movie_id: ObjectId(movieId),
     text: comment,
     date: date
    }
  //console.log(commentDoc)

  return await comments.insertOne(commentDoc)
} catch (e) {
  console.error(`Unable to post comment: ${e}`)
  return { error: e }
}
  }

  /**
   * Updates the comment in the comment collection. Queries for the comment
   * based by both comment _id field as well as the email field to doubly ensure
   * the user has permission to edit this comment.
   * @param {string} commentId - The _id of the comment to update.
   * @param {string} userEmail - The email of the user who owns the comment.
   * @param {string} text - The updated text of the comment.
   * @param {string} date - The date on which the comment was updated.
   * @returns {DAOResponse} Returns an object with either DB response or "error"
   */
  static async updateComment(commentId, userEmail, text, date) {
//console.log(commentId)
try {
  // TODO Ticket: Create/Update Comments
  // Use the commentId and userEmail to select the proper comment, then
  // update the "text" and "date" fields of the selected comment.
  const updateResponse = await comments.updateOne(
    {$and: [{ _id: ObjectId(commentId) },
    { email: userEmail }]},
    { $set: { text: text, date: date} },
    { upsert: true}
  )
  return updateResponse
} catch (e) {
  console.error(`Unable to update comment: ${e}`)
  return { error: e }
}
  }

  static async deleteComment(commentId, userEmail) {
/**
Ticket: Delete Comments

Implement the deleteOne() call in this method.

Ensure the delete operation is limited so only the user can delete their own
comments, but not anyone else's comments.
*/

try {
  // TODO Ticket: Delete Comments
  // Use the userEmail and commentId to delete the proper comment.
  const deleteResponse = await comments.deleteOne({
    $and: [{ _id: ObjectId(commentId) },
    { email: userEmail }]
  })

  return deleteResponse
} catch (e) {
  console.error(`Unable to delete comment: ${e}`)
  return { error: e }
}
  }

Can you help me whats wrong in here? Really interested in the solution.

Thank you very much have a wonderful day a head! :blush:

Hi @Ur_Sonka, your queries & pipelines looks good to me.
Having said that, I just want to confirm that, did you restart your server after making all those changes?
If not, please try restarting the server, as it might happen that nodemon missed all these updates in your code.

In case you have any doubts, please feel free to reach out to us.

Thanks and Regards.
Sourabh Bagrecha,
Curriculum Services Engineer

Thank you for your reply.
I will search for other parts of the site to get the solution.

I was learning new things and let keep running the mflix site.
The error messages are the following:

Can you take a short look on them? Thank you! :blush:

Note that there is a concept of an implicit $and in queries.

The following 2 queries are equivalent:

query_1 = { $and : [ { _id: ObjectId(commentId) } , { email: userEmail } ] } ;
query_2 = { _id: ObjectId(commentId) , email: userEmail } ;

Since they are equivalent, I don’t think that’s the reason for the issue you have.

But, I do not think that you want upsert:true in updateComment().

I repair both of them.
I changed the upsert value couse of the panic it wasnt work, now i write back to false. I also change the $and paramater. (Unfortunately the problem still exsist error 500.)
Thank you for your advices! :blush:

Hi @Ur_Sonka, as far as I can see there are 3 errors that need to be resolved.
First: “Cannot set headers once they are sent to the client.”

This occurs whenever we are updating the headers after returning the response, please make sure that you are performing all the configs and other request/response-related changes before returning the response. Also, this is a known issue and can be explored more here.

Second: “Duplicate key error while updating the docs”

None of the exercises require you to update _id field, and it is also not, please make sure that none of your update commands are modifying the _id field, also _id field is immutable in MongoDB.

Third: “Arguments passed must be a single string of 12 bytes or a string of 24 hex chars”

Please place a console.log at the start of the getMovieByID method to determine whether the id you are getting from the function arguments is a string of 24 hex chars or not.
And try to invoke this method and make sure that it is working as expected.

I hope it helps.

In case you have any doubts, please feel free to reach out to us.

Thanks and Regards.
Sourabh Bagrecha,
Curriculum Services Engineer