0

I need to merge 2 objects of objects. I have tried both the spread operator and Object.assign. But my end result still is showing just the results of the second objects.

let obj1= { ratings: [], stats: {restaurants: 0, bnb: 0, hotel: 0}, calls: [ {f_name: 'Harry', l_name: 'Potter', address: 'Godrics Hollow', colors:['red', 'gold']}, {f_name: 'Ron', l_name: 'Weasley', address: 'The Burrow', colors:['orange', 'black']}, {f_name: 'Hermione', l_name: 'Granger', address: '123 London', colors:['red', 'blue']}, ] } let obj2= { ratings: [], stats: {restaurants: 3, bnb: 2, hotel: 1}, calls: [ {f_name: 'Jon', l_name: 'Snow', address: 'The Wall', colors:['white', 'brown']}, {f_name: 'Robb', l_name: 'Stark', address: 'Winterfell', colors:['red', 'white']}, {f_name: 'Sansa', l_name: 'Stark', address: 'The North', colors:['white', 'silver']}, {f_name: 'Arya', l_name: 'Stark', address: 'Essos', colors:['blue', 'silver']}, {f_name: 'Bran', l_name: 'Stark', address: 'Kings Landing', colors:['purple', 'green']} ] } let obj3 = { ...obj1, ...obj2 }; console.log(obj3); console.log('---------------------------------------------'); let obj4 = Object.assign(obj1, obj2); console.log(obj3);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Both ways are returning: obj2.

I need:

{ ratings: [], stats: {restaurants: 3, bnb: 2, hotel: 1}, calls: [ {f_name: 'Harry', l_name: 'Potter', address: 'Godrics Hollow', colors:['red', 'gold']}, {f_name: 'Ron', l_name: 'Weasley', address: 'The Burrow', colors:['orange', 'black']}, {f_name: 'Hermione', l_name: 'Granger', address: '123 London', colors:['red', 'blue']}, {f_name: 'Jon', l_name: 'Snow', address: 'The Wall', colors:['white', 'brown']}, {f_name: 'Robb', l_name: 'Stark', address: 'Winterfell', colors:['red', 'white']}, {f_name: 'Sansa', l_name: 'Stark', address: 'The North', colors:['white', 'silver']}, {f_name: 'Arya', l_name: 'Stark', address: 'Essos', colors:['blue', 'silver']}, {f_name: 'Bran', l_name: 'Stark', address: 'Kings Landing', colors:['purple', 'green']} ] } 
4
  • You're asking for deep merging which is not possible with standard JS functions. You'l have to write your own deep nesting routine Commented Aug 7, 2020 at 22:42
  • see stackoverflow.com/questions/46202433/… Commented Aug 7, 2020 at 22:43
  • Why not concat the calls arrays for obj3, e.g. obj3.calls = [...obj1.calls, ...obj2.calls]? Same for stats and ratings--combine by hand? I'm not sure if this is what you're asking for though. Commented Aug 7, 2020 at 22:44
  • Object.assign(obj1, obj2) is used to copy the properties from source(obj2) to target(obj1). If the properties already exists in obj1, then it will be replaced by obj2. It's not like deep merging of property values. . Commented Aug 8, 2020 at 10:09

2 Answers 2

3

JS spread function only helps in shallow merging. In your case, you need deep merging so you need to write custom logic for it.

If the object properties will be same always, you can use this.

let obj3 = Object.assign({}, obj1); obj3.ratings.push(...obj2.ratings); obj3.calls.push(...obj2.calls); Object.keys(obj2.stats).forEach(function(key,index) { obj3.stats[key] += obj2.stats[key]; }); console.log(obj3); 

Note: This wont work if your object properties are changed.

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

Comments

1

Is this what you're going for?:

let obj3 = { ratings: [ ...obj1.ratings, ...obj2.ratings ], stats: { ...obj1.stats, ...obj2.stats }, calls: [ ...obj1.calls, ...obj2.calls ] }; 

1 Comment

Rajat Sharma's answer is much better if you want to sum the stats. My answer will just overwrite the stats of obj1 with the stats of obj2

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.