11

var a = {
  1: {
    687: {
      name:'test1'
    }
  }
}
var b = {
  1: {
    689: {
      name:'test2'
    }
  }
}
var c = {
  ...a,
  ...b
}
console.log(c)

I was expecting the result to be :

{
  1: {
    687: {
      name:'test1'
    },
    689: {
      name:'test2'
    }
  }
}

But, it is :

{
  1: {
    689: {
      name:'test2'
    }
  }
}

Am I using spread operator wrong? What is the most efficient way to merge two objects? I made a function which iterates through each key in the objects, it works but I think it's not the write way.

Object.assign({},a,b) also returns the same (first result, which I don't want).

I went through the question How can I merge properties of two JavaScript objects dynamically?

But It doesn't answer my question. this answer (https://stackoverflow.com/a/171256/1352853) is also not what I want.

Thanks in advance.

11
  • 1
    stackoverflow.com/a/383245/2008111 might not answer the question but solve the problem :) Commented Jun 23, 2017 at 12:51
  • 2
    Possible duplicate of How can I merge properties of two JavaScript objects dynamically? Commented Jun 23, 2017 at 12:52
  • 3
    You need to merge the sub objects: var c = { 1: { ...a.1, ...b.1 } }; Commented Jun 23, 2017 at 12:57
  • 1
    @Ataomega um, I wrote it in that comment. Commented Jun 23, 2017 at 12:59
  • 2
    @JaredSmith upvoted though a.1 is invalid, should be a[1] or in full var c = { 1: { ...a[1], ...b[1] } } (only chrome 60+ and FF55+ support too.) Commented Jun 23, 2017 at 13:05

5 Answers 5

8

lodash merge actually does what I exactly need.

https://blog.mariusschulz.com/2015/03/30/combining-settings-objects-with-lodash-assign-or-merge

// Defined within your component
var defaultSettings = {
    strictMode: true,
    formatting: {
        finalNewline: true,
        quotes: "double"
    }
};

// Provided by the developer using your component
var userSettings = {
    formatting: {
        quotes: "single"
    }
};

var assignedSettings = _.assign({}, defaultSettings, userSettings);

// {
//     strictMode: true,
//     formatting: {
//         quotes: "single"
//     }
// }

var mergedSettings = _.merge({}, defaultSettings, userSettings);

// {
//     strictMode: true,
//     formatting: {
//         finalNewline: true,
//         quotes: "single"
//     }
// }

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

2 Comments

While handy, this should not be the accepted solution. It asks for a javascript solution and not a lodash utility, so either go with Object.assign({}, obj1, obj2) or the object spread operator I'd say.
it's cool to know about lodash merge method, nothing wrong about that.
1

The spread operator is for arrays and iterable objects. If x = ['A','B','C']; Then ...x is equals to writing x[0], x[1], x[2].

You want to merge the nested objects key by key from each object, not replace the previous values.

let key;
let c = {};
for (key in a) {
    c[key] = Object.assign({}, a[key]);
}
for (key in b) {
    c[key] = Object.assign(c[key] || {}, b[key]);
}

4 Comments

How deep would it go?
This one will go only 1 level deep. For deeper levels, a recursive function is needed
@AtaMohammadi Pretty deep! xd
0

Would this help?

let person = {PersonID: 1, PersonName:'John'};
let newName = 'Nation';
let newSubName ='NationName';
let newValue = 'USA';
 person = {
      ...person,
      ...{ [newName]: { [newSubName]: newValue } },
 }
Expected result:
{person:{PersonID:1, PersonName:'John', Nation:{NationName:'USA'}}}

Comments

0

Example with using of spread operator:

const nameObject = { name: 'John' };
const surnameObject = { surname: 'Cool' };
const mergedObject = { ...nameObject, ...surnameObject };

Example with using Object.assign:

const mergedObject = Object.assign(nameObject, surnameObject);

For some more advanced cases you can use lodash methods: merge and mergeWith.

Comments

0

I recently learn this concept

const profile = {
    name: "Bob",
    age: 29,
    address: {
       city: "New York",
       zipcode: "94101"
    }
}

const updates = {
    age: 30,
    address: {
       zipcode: "94109",
       country: "USA",
    }
}


let output = {...profile, ...updates, address: {...profile.address, ...updates.address} }  

console.log(output)  

3 Comments

This answer merges two objects but they are related; the OP is trying to merge two unrelated objects into a single object. How does your example apply to the OP's scenario?
If he does some modification in variable c like var c = { 1: { 687: { ...a[1][687] }, 689: { ...b[1][689] } } }
Quite possibly. So why not model this in your answer?

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.