Search code examples
node.jsmongodbmongoskin

Need to "build" a "key" name in Mongoskin request


I am working on a Node.js app, using Mongoskin and Express.js. First, here is a simple overview of the MongoDB collection I'm working with :

db.profiles.find()
{ "_id" : ObjectId("5559e6ad8da0dc030010cf64"), 
  "userid" : "63e9c530-fd60-11e4-a30c-f3b609480e30", 
  "emailaddr" : { "value" : "x@y.fr", "share" : false },
  "fullname" : { "value" : "Azerty Ytreza", "share" : true },
  "telnumber" : { "value" : "0606060606", "share" : true }

As you can see, I'm storing multiple objects, following the same architecture (value + boolean) Depending on what the user will want to share / don't share anymore, I will need to update the "share" value of the good Object.

First, I can't find out how to modify a value stored in an Object. Referring to this : Modify nested Object value , I thought I could do like this in my Mongoskin requests :

db.collection.update(  { _id:...} , { $set: { some_key.param2 : new_info  } } 

In this case, Node.js is reporting an error, saying "SyntaxError: Unexpected token '.' ".

The thing is that as I said earlier, depending on what the user will want to modify, I won't modify the same "key". So, I need to build the key name. Example: if the user wants to modify the "share" value of his email address, I will need to update emailaddr.share. But how can I do this using Mongoskin? I tried different solutions, but it's impossible to do things like :

var key = "emailaddr",
    newVal = "true";

key += ".share";

db.collection.update( { _id: ... } { $set: { key : newval } }

Solution

  • Say you want to change the share status of the fullname property :

    > var property = "fullname"
    > var value = false
    

    You have to dynamically build the object {"fullname.share": false}¹ :

    > var updt = {}
    > updt[property + ".share"] = value
    

    Then use that object as the parameter to $set:

    > db.test.update({"_id" : ObjectId("5559e6ad8da0dc030010cf64")},
    ...              {$set: updt})
    //                      ^^^^
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    


    1 As a side note, as explained in the doc the quotes (" or ') are mandatory around the name of an object property if it contains a . -- hence the syntax error you mentioned in your question.