2

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 } } 

2 Answers2

3

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));
alotropico
  • 1,904
  • 3
  • 16
  • 24
1

your return statement will overwrite the value to key {b: 10, c:10} with {b:30}, what you are getting, you can use lodash library's ``set``` function that does the same thing that you are trying to achive

you can use below code to change the value

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

function getObj(obj, key) {
return obj[key];
}

function change(obj, keys, value) {
 let newObj = JSON.parse(JSON.stringify(obj));
 let str = keys.split('.');
 str.reduce( (acc, curr, index) => {
  if(index === str.length -1) {
    acc[curr]= value;
    return acc
  }else {
    return getObj(acc, curr);
  }
 }, newObj );
return newObj;
}

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

console.log(change(a, 'a.c', 20))
Alok Takshak
  • 282
  • 1
  • 6