Sunday 19 March 2017

Partially updating nested objects with multiple values Express.js MongoDB

First of all, I have read this stack overflow entry which addresses this problem partially but I need to dynamically add multiple entries and cannot apply the answers there to this problem.

I have a website with polls (using express and the mongodb driver) and I want users to be able to add additional options to the polls after they have submitted it (they can only add additional items, they cannot edit preexisting items).

All options (the possible answers) are labelled as answer followed by a number (maximum of 5).

So in the database we have:

{
    "_id": {
        "$oid": "58cdf0023cefa56136afb50f"
    },
    "question": "Who is the best Bob?",
    "options": {
        "answer1": {
            "option": "Bob Dylan",
            "votes": 2
        },
        "answer2": {
            "option": "Bob Geldof",
            "votes": 0
        }
    }
}

So with this entry, the user can add up to three additional answer options.

When I hard-code the additional answer name (e.g. answer3 in this db example) I can update the nested options property.

var toInsert = { options: 
   { answer3: { option: 'Bob Saget', votes: 0 },
     answer4: { option: 'Bob Marley', votes: 0 } } }

  db.collection('questions')
  .findOneAndUpdate({"_id": questionId}, {$set : {'options.answer3': [toInsert.answer3]}}, {upsert: true}, (err, result) => {
    if (err) return res.send(err)
    res.send("worked");
  })

EDIT: I have just realized his has a bug in it also, so I can't even hard-code the answer properly. However, I will leave this here for clarity.

But what I need to do is dynamically update that nested options object with 1-3 possible new options (depending on what the user wants) and leave the pre-existing data alone in the options object. In the example code above, I would want to insert both answer3 and answer4 from toInsert.

I'm very new to Node and MongoDB and my idea of "Hey, I can put it through a for loop" seems like a bad idea even if I could get it to work.



via swhizzle

No comments:

Post a Comment