javascriptjsonmapreduceobject-properties

Modify json properties from string dynamically


I have JSON object

var a = { a: { b: 10, c: 10 } } 

I want a method that can change JSON object dynamically. Suppose when i supply object , string and a value to method it should return updated JSON object

change(a, 'a.b', 30) 

change method is as follows:-

function change(obj, str, val) {
  const newObject = str.split('.').reverse()
      .reduce((a,p,i) => { 
          if(i===0) a[p] = val 
          else { let b = {}; b[p] = a; a = b} 
          return a;
       },{})
   return {  ...obj, ...newObject } 
}

it should return

{ a: { b : 30, c: 10 } } 

without modifying other json fields but it is currently returning

 { a: { b : 30 } } 

Solution

  • This is one way to do it:

    var a = { a: { b: 10, c: 10 } };
    var b = { a: { b: { c: 10 } } };
    
    function change(obj, str, val) {
      // get parts of the string as an array
      const prop = str.split('.');
      
      // deep clone the object (so you don't modify the original 'a' object, insted you get a new one returned)
      const newObj = {...obj};
      
      // save a reference to the new object
      let target = newObj;
      
      prop.forEach((el, i) => {
        if(i < prop.length-1) {
          // replace the reference for a nested reference
          target = target[el];
        } else {
          // if it's the last 'prop' item, change the value
          target[el] = val;
        }
      });
      
      // return the new object
      return newObj;
    }
    
    console.log(change(a, 'a.b', 30));
    
    console.log(change(b, 'a.b.c', 50));