Accessing _id in MongoDB with Express PUT request (Voting App Challenge)

Hey all!

I am not sure how to access the _id tag in MongoDB when using findOneAndUpdate(). I am currently using my own made up id system that is just the length of the database + 1 (which will cause major issues when someone deletes an entry) called “question_id”

Due to the nature of this project being in a lot of different pages, this is going to be a lot of code but hopefully all very easy to follow (I think my problem is a simple one).

Let me show you the mongoDB entry and the findOneAnUpdate() call:

db object example:

{
   "_id": {
       "$oid": "58c854c9fa4a5d0efd6de8d8"
   },
   "question_id": 1,
   "question": "Jelly or Ice-Cream?",
   "answer1": "Jelly",
   "answer2": "Ice-Cream",
   "answer1_votes": 8,
   "answer2_votes": 0
}

After creating a question they are displayed on a page like so:

<div class="row" id=<%= result[i].question_id %>>
  <button class="answer-button col-md-3" id="answer1" name="answer1"><%= result[i].answer1 %></button>
  <button class="answer-button col-md-3" id="answer2" name="answer2"><%= result[i].answer2 %></button>
</div>

With the parent div’s ID being the question_id element.

Then the fetch query when someone votes on either:

  $('.answer-button').on('click', function () {
    let question_id = $(this).parent().attr("id");
    let question_vote = $(this).attr('id') + "_votes";

    fetch('submitVote', {
      method: 'put',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({
        'question_id': question_id,
        'questionToUpdate': question_vote
      })
    }).then(res => {
      if (res.ok) return res.json()
    }) .then(data => {
        window.location.reload()
      })

  })

Where you can see I get the ID from which button they clicked on and I also send the question_id in the req.body.

And then:

exports.submitVote = (req, res) => {
  console.log(req.body)
  db.collection('questions')
  .findOneAndUpdate({"question_id": parseInt(req.body.question_id)}, {$inc : {[req.body.questionToUpdate] : 1} }, (err, result) => {
    if (err) return res.send(err)
    res.send(result)
  })
}

Where I change the question_id to a number and use it to find and update the relevant question and the number of votes.

Now, I wanted to do this with result[i]._id, which through the console.log saves the correct id! I get “58c854c9fa4a5d0efd6de8d8” for example.I didn’t have to specify result[i]._id[’$oid’] for example.

The problem comes when I try to use the data to update the database (req.body._id would have been the id from result[i]._id):

exports.submitVote = (req, res) => {
  console.log(req.body)
  db.collection('questions')
  .findOneAndUpdate({"_id": req.body._id}, {$inc : {[req.body.questionToUpdate] : 1} }, (err, result) => {
    if (err) return res.send(err)
    res.send(result)
  })
}

It doesn’t find "“58c854c9fa4a5d0efd6de8d8” and increment the vote count. I assume the problem is that the $oid is contained within an object within _id, but I don’t know how I can access it?

I hope this made sense, it’s not the easiest problem to explain,
Thanks

You are probably comparing a string to an Object ID. You can use:

var myId = new mongoose.Types.ObjectId( req.body._id)
findOneAndUpdate({"_id": myId})

I’m not using mongoose, just the MongoDB driver on the npm. Any idea how I would do it with that? Thanks for the fast reply!

I’ve only used mongoose, but the MongoDB docs show an ObjectID(string) function that looks like it operates the same way: https://docs.mongodb.com/v3.2/reference/method/ObjectId/#ObjectId

Awesome, I’ll check it out now and report back :slight_smile:

Got it!

You have to add:

const ObjectId = require('mongodb').ObjectID;

And then I passed it in and now it works :).

Thanks for the help!