0

I want to access (get/set) a nestedJS object with a variable.

For example, static it would look like that:

$obj.children.12.children.32.Name; // Returns "Foo"

Now I have an "Route" array (or whatever is easy too handle):

["children",12,"children",32,"Name"]

And want to get the value of the object.

Like I read here on Stackover, there is an very easy way to do it (Solution 2).

But, now I want to change the value for the passed key/route. Is there any way to do that?

Thank you very much!

Edit: I can use jQuery/Angluar-Features, if it helps me.

Community
  • 1
  • 1
Tream
  • 1,049
  • 2
  • 13
  • 29
  • 3
    Assuming you write a getter like `getPath(obj, pathArray)`, you can write a setter `setValueAtPath(obj, pathArray, valToStore)` that acts exactly the same as `getPath` except that its loop stops at the second-to-last object (e.g., `i < pathArray.length - 1`) and does `secondToLastItem[finalKey] = valToStore`. – apsillers Oct 28 '14 at 12:49
  • Thank you for your reply, @apsillers. I have problems to understand how a setter could work. If I do secondToLastObj[finalKey] = valToStore - the value is stored in the variable 'secondToLastObj', not in the object itsself, right? But I want to change it in the "big" object with all data. – Tream Oct 28 '14 at 12:51
  • @Tream it will be changed in the big object too. The variable `secondToLastObj` only points to the part in the big object, the data is not actually stored there. – parchment Oct 28 '14 at 12:54
  • @apsillers, I will try it out, and I´m sure it will work, since you says so. But why? I know the Syntax from PHP: foreach($x as $k=>&v){}. Now changes in $v will affackt $x too. But how does it work in a simple for() loop without any additional syntax? Thank you very much for your help! – Tream Oct 28 '14 at 13:01

1 Answers1

1

Borrowing code from the accepted answer on the post you've linked to, we can trivially make a getter:

function getFromPath(obj, pathArray) {
  var res = obj;
  for (var i=0; i<pathArray.length; i++) { res = res[pathArray[i]]; }
  return res;
}

We call this with getFromPath($obj, ["children",12,"children",32,"Name"]);.

Since you want to transform this getter function into a setter, you want to set a property on the second-to-last object. We can do this by stopping the loop one iteration early and then performing set with the final property name on the object:

function setToPath(obj, pathArray, valueToSet) {
  var res = obj;

  // note the `length - 1` here: we don't go to the end of the path 
  for (var i=0; i<pathArray.length - 1; i++) { res = res[pathArray[i]]; }

  // res is now the second-to-last object in the path,
  // and we'll set the final value as a property on the object

  var finalKey = pathArray[pathArray.length-1];
  res[finalKey] = valueToSet;
}

We call this with setToPath($obj, ["children",12,"children",32,"Name"], "Dana");.

Alternatively, if you wanted to do this with just a getter, you could shorten your path by one item and perform the set on the result from the getter:

var secondToLast = getFromPath($obj, ["children",12,"children",32]);
secondToLast["Name"] = "Dana";
Community
  • 1
  • 1
apsillers
  • 112,806
  • 17
  • 235
  • 239
  • So it works 100% perfectly. Thank you very much! For everybody, who wants to copy&paste this: notice, that path[i] in line 5 should be pathArray[i]. – Tream Oct 28 '14 at 13:10