8

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.

Ata Mohammadi
  • 3,430
  • 6
  • 41
  • 69

2 Answers2

6

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"
//     }
// }
Ata Mohammadi
  • 3,430
  • 6
  • 41
  • 69
  • 1
    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. – spoutnik Jun 14 '19 at 14:55
  • it's cool to know about lodash merge method, nothing wrong about that. – Vasyl Gutnyk May 08 '20 at 07:21
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]);
}
Kulvar
  • 1,139
  • 9
  • 22