Shadow Shadow -4 years ago 148
Javascript Question

Access MongoDB nested object using variables

Using the npm package mongojs, I need to access nested objects using a variable. The following, however, does not work:

let userID = req.user._id,
marketName = req.body.marketName,
itemName = req.body.item.itemName,
crossOff = req.body.item.isCrossed;

markets.updateOne(
{
_id: userID,
"marketList.marketName": marketName
},
{$set : {`marketList.$.shoppingList.${itemName}.isCrossed`: crossOff}},
(err, doc) => {
if(err) { res.status(400).send('Bad Request') }
else { res.status(204) }
res.end();
});
});


As you cannot use template strings in this situation, hence the
unexpected template string
error.



I am aware that it is possible to use bracket-notation to use a variable as a key, however, this will not help my situation since I am unable to set a variable with the entire key stored in it as a string.



To help, here is a sample the document structure:

{
_id: ObjectId(...),
marketList: [
{ marketName: 'ralphs',
shoppingList: {
"cookies": { itemName: "cookies", isCrossed: false },
"moar cookies": { itemName: "moar cookies", isCrossed: true }
},
{
marketName: 'gelsons',
shoppingList: {
"even moar cookies": { itemName: "even moar cookies", isCrossed: true }
}
}
]
}


What are my options?

Answer Source

You can create the query in advance, that way bracket notation can be used for the key

let userID   = req.user._id,
  marketName = req.body.marketName,
  itemName   = req.body.item.itemName,
  crossOff   = req.body.item.isCrossed,
  query      = {};

query["marketList.$.shoppingList." + itemName + ".isCrossed"] = crossOff;

markets.updateOne({
        _id: userID,
        "marketList.marketName": marketName
    }, {
        $set: query
    }, (err, doc) => {
        if (err) {
        res.status(400).send('Bad Request');
        } else {
        res.status(204);
        }
        res.end();
    });
});
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download