1

Is possible dynamically add properties to nested object in Typescript ? Because my object is dynamic. In one case i have obj.

[
  {someObject},
  {
    prop1:1,
    columns: [
      components: [
        columns: [
          components:[
            {
              type: number,
              key: 'key1'
            },
            {
              type: textfield,
              key: 'key2'
            }
          ]
        ]
      ]
    ]
  }
]

And for example for object with key key2 i need add some flag. And in another case i get object less nested. Does exists any for example lodash function for this operation, or i have to iterate this object by recursion ?

Tom
  • 77
  • 7
  • Does this answer your question? [Find by key deep in a nested array](https://stackoverflow.com/questions/15523514/find-by-key-deep-in-a-nested-array) – user120242 Jun 23 '20 at 09:17

1 Answers1

2

You will have to recursively search. Thankfully this is not too difficult to implement:

const findAndUpdate = ($obj, $key, $val) => {
  Object.keys($obj).includes($key) ? 
    $obj[$key] = $val
    : Object.values($obj).forEach($nestedObj => findAndUpdate($nestedObj, $key, $val));
  
  return $obj;
}

I used Object.<method> instead of lodash methods so that this can be easily replicated accross enviroments. This function will take in an initial object, the key you want to update and the value that you want to update it to.

Usage:

const foo = {
   b: {
      c: {
        d: 5
      }
   }
}

findAndUpdate(foo, "d", 56);
console.log(foo) // -> { b: { c: { d: 56 } } } }

It checks if the key exists in the current layer of the object. If it doesn't then we call the function again for each object in the current layer - passing in the original object as a reference. If it does find a key in the current layer, then it will update the object that the reference points to. Eventually after the stack is cleared then we return our original updated object. Obviously if no keys are found that match the target key originally passed in then the object will remain unchanged.

If you want more customisation you could change the $val to take in a function $func instead:

const findAndUpdate = ($obj, $key, $func) => {
  Object.keys($obj).includes($key) ? 
    $obj[$key] = $func($obj[$key])
    : Object.values($obj).forEach($nestedObj => findAndUpdate($nestedObj, $key, $val));
  
  return $obj;
}

Then you can now do something like this:

findAndUpdate(foo, "d", old => old+1 );
console.log(foo) // -> { b: { c: { d: 6 } } } }
Dylan Kerler
  • 2,007
  • 1
  • 8
  • 23