0

I have two js objects

const first = { 
  obj1: { f11: "v11", f12: "v12" }, 
  obj2: { f21: "v21" } 
}

const second = { 
  obj1: { f11: "new_value" }, 
  obj3: { f: { ff: { fff: "v"} } } 
}

How can I update first javascript object only with object2's leaves values and get

const first = { 
  obj1: { f11: "new_value", f12: "v12" }, 
  obj2: { f21: "v21" },
  obj3: { f: { ff: { fff: "v"} } }  
}  

UPD: I tried Object.assign but result is

const first = { 
  obj1: { f11: "new_value" }, 
  obj2: { f21: "v21" },
  obj3: { f: { ff: { fff: "v"} } }  
} 

I loose some of internal fields

6
  • take a look at here stackoverflow.com/questions/10430279/… Commented Jul 31, 2017 at 6:10
  • 1
    Why you are using const? Any specific reason? Commented Jul 31, 2017 at 6:10
  • 3
    Possible duplicate of How to deep merge instead of shallow merge? Commented Jul 31, 2017 at 6:15
  • 2
    @MohammadUsman A reason is that always prefer const. Mutability should be opt-in, and even though the source object may be mutated itself, const just means something can't be reassigned or redeclared, doesn't mean you can't mutate a property. Commented Jul 31, 2017 at 6:18
  • @AndrewLi Thanks You. I've got the point now.. Commented Jul 31, 2017 at 6:22

2 Answers 2

1

This requires deep merge. In jquery you can use $.extend.

Javascript equivalent is:

const first = { 
  obj1: { f11: "v11", f12: "v12" }, 
  obj2: { f21: "v21" } 
}

const second = { 
  obj1: { f11: "new_value" }, 
  obj3: { f: { ff: { fff: "v"} } } 
}

function extend(){
    for(var i=1; i<arguments.length; i++)
        for(var key in arguments[i])
            if(arguments[i].hasOwnProperty(key)) { 
                if (typeof arguments[0][key] === 'object'
                    && typeof arguments[i][key] === 'object')
             				extend(arguments[0][key], arguments[i][key]);
                else
                   arguments[0][key] = arguments[i][key];
             }
    return arguments[0];
}

console.log("Merged object is: " + JSON.stringify(extend(first, second)))

Sign up to request clarification or add additional context in comments.

Comments

1

You could use a recursive approach by checking the type and assigning new value.

function merge(source, target) {
    Object.keys(source).forEach(function (key) {
        if (!source[key] && typeof source[key] === 'object') {
            target[key] = target[key] || (Array.isArray(source[key]) ? [] : {});
            return merge(source[key], target[key]);
        }
        target[key] = source[key];
    });
}

const first = { obj1: { f11: "v11", f12: "v12" }, obj2: { f21: "v21" } },
      second = { obj1: { f11: "new_value" }, obj3: { f: { ff: { fff: "v"} } } };

merge(second, first);
console.log(first);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.