2

I have an object that is decoded from a json:

var data = [{
    "parentSeries":1,
    "children":[{
        "BusinessRule":"ChrisTest2",
        "ID":"ChrisTest2||3",
        "childsub":3,
        "jsonCondition":{
            "parentSeries":1,
             "children":[{
                 "RuleDefinition":"ChrisTest2||3",
                 "ID":"ChrisTest2||3||CondField1",
                 "Field":"CondField1",
                 "Test":"=1"
             },{
                 "RuleDefinition":"ChrisTest2||3",
                "ID":"ChrisTest2||3||CondField2",
                "Field":"CondField2",
                "Test":"=2"
             }]
        }
    }]
}]

I want to update any elements of this object dynamically. I have an array that shows me where the property I want to update is. eg:

var splitMap = ["jsonCondition", "children", "0", "Test"]

I have a value I want to update the final entry in this array with coming in (newValue), and I've got a bit of code to update the particular nested item to contain this new value:

if (splitMap.length > 0) {
    var newdata = data;
    for (var p = 0; p < splitMap.length-1; p++) {
        newdata = newdata[splitMap[p]];
    }
    newdata[splitMap[splitMap.length - 1]] = newValue;
}

But I can't figure out a way to get this updated into the original data! I basically want to do

oldobject['jsonCondition']['children'][0] = newdata

or

oldobject['jsonCondition']['children'][0]['Test'] = newValue

...but I want it work out the keys and depth of this path based on the content and length of the map array. I have jquery on our platform if that helps ($.each?)! Any ideas? Thanks :)

chrisb
  • 21
  • 2
  • have you thought of writing a recursive function that uses $.each and checks to see if the next level down is an object? – josh123a123 Feb 26 '15 at 18:27
  • where does `splitMap` array come from? Starting there you might be able to store an object reference that would make it even easier – charlietfl Feb 26 '15 at 18:28
  • Thanks all, I was able to use @Labithiotis answer on the duplicate question :) – chrisb Feb 27 '15 at 16:45

1 Answers1

1

You should be able to just walk you way down your object by using the bracket notation [] to access each property in turn:

var curr = oldobject;   // this keeps track of our current position
for (var i=0; i < splitMap.length-1; i++) {
    if (curr.hasOwnProperty(splitMap[i]) {
        curr = curr[splitMap[i]];
    }
    else {
       // your map is wrong! Up to you how to handle this error
    }
}
curr[splitMap[i]] = newValue;    // for the last property, we set the value
Matt Burland
  • 44,552
  • 18
  • 99
  • 171
  • Thanks! That's pretty much where I got to (although your loop is better, thanks!).My issue is that this updates the lowest nested object, but I can't work out how merge that with the parent 'oldobject' object, in the right context, and via the splitMap array rather than hard-coding the object reference (because the splitMap array could be anything, and any depth). i.e., I want to do oldobject['jsonCondition']['children'][0] = curr, but I want it to be programmatic. – chrisb Feb 27 '15 at 09:47
  • @chrisb: Not sure what you mean. You are updating the property at the lowest level of the *original object*. There is no need to *merge* anything. That's why we only loop until the penultimate property if your `splitMap`. Because we want to assign to the very last one. – Matt Burland Feb 27 '15 at 13:48