Reputation: 20436
I have two objects like this:
var a = {prop:{a:'1'}}
var b = {prop:{b:'1'}}
I want to merge the two objects using Object.assign. I tried this:
var c = Object.assign(a,b)
> {prop:{b:'1'}}
How do I get this output:
{prop:{a:'1',b:'1'}}
In short, I want to do Object assign on every sub Objects => (IF PROPERTY EXISTS, CHECK CHILDREN FIRST IF IT AS OBJECT, DO NOT OVERIDE)
Upvotes: 5
Views: 6598
Reputation: 8239
Since a and b in your case contains a property with same name, when you do something like Object.assign(a,b)
the prop
property of b overwrites and not merge the prop. Reference
Try the following:
var a = {prop:{a:'1'}}
var b = {prop:{b:'1'}}
var c = {};
c.prop = Object.assign({},a.prop,b.prop);
console.log(c);
Or
You can write your own custom function which can merge the values of the objects with same properties.
Try the following:
function merge(source, target) {
Object.keys(source).forEach((k) => {
if (source[k].constructor.toString().indexOf('Object') > -1 && target[k]) {
merge(source[k], target[k]);
return;
}
target[k] = source[k];
});
return target;
}
var a = {prop:{a: '1'}};
var b = {prop:{ b: '1'}};
var c = {};
[a,b].forEach((e)=>merge(e, c));
console.log(c);
Upvotes: 2
Reputation: 386654
You could use a deep merge function for every level of the object.
The function deepMerge
works as single function for a given target or as callback for Array#reduce
, where an array of objects is iterated and an empty object is supplied as startvalue
for reducing.
The function/callback itselft has two parameters, one for the target object and one for the source object where all entries are taken and iterated.
A value of the object is checked and if the type is an object, then a recursive call of deepMerge
is done with a a new target property, if not given or to an exitent property.
If the value is not an object, the value is assigned to target
with the given key.
The result is a new object with all properties of the given objects.
function deepMerge(target, source) {
Object.entries(source).forEach(([key, value]) => {
if (value && typeof value === 'object') {
deepMerge(target[key] = target[key] || {}, value);
return;
}
target[key] = value;
});
return target;
}
var a = { prop: { a: '1' } },
b = { prop: { b: '1' } },
c = [a, b].reduce(deepMerge, {});
console.log(c);
Upvotes: 9