deep merge objects with AngularJS
angularjs, javascript
Solution
Angular 1.4 or later
Use `angular.merge`:
Unlike `extend()`, `merge()` recursively descends into object properties of source objects, performing a deep copy.
angular.merge(object1, object2); // merge object 2 into object 1
Older versions of Angular:
There is no reason a simple recursive algorithm shouldn't work :)
Assuming they're both the result of JSON.stringify or similar:
function merge(obj1,obj2){ // Our merge function
var result = {}; // return result
for(var i in obj1){ // for every property in obj1
if((i in obj2) && (typeof obj1[i] === "object") && (i !== null)){
result[i] = merge(obj1[i],obj2[i]); // if it's an object, merge
}else{
result[i] = obj1[i]; // add it to result
}
}
for(i in obj2){ // add the remaining properties from object 2
if(i in result){ //conflict
continue;
}
result[i] = obj2[i];
}
return result;
}
Here is a working fiddle
(Note, arrays are not handled here)
Problem
Normally to shallow copy objects I would use `angular.extend()` Here's an example of that: ``` var object1 = { "key": "abc123def456", "message": { "subject": "Has a Question", "from": "example1@example.com", "to": "example2@example.com" } }; var object2 = { "key": "00700916391" }; console.log(angular.extend({}, object1, object2)); ``` Would give us: ``` { "key": "00700916391", "message": { "subject": "Has a Question", "from": "example1@example.com", "to": "example2@example.com" } } ``` But what if I wanted to merge objects so that parent keys are not over written by child objects: ``` var object1 = { "key": "abc123def456", "message": { "subject": "Has a Question", "from": "example1@example.com", "to": "example2@example.com" } }; var object2 = { "key": "00700916391", //Overwrite me "message": { //Dont overwrite me! "subject": "Hey what's up?", //Overwrite me "something": "something new" //Add me } }; console.log(merge(object1, object2)); ``` Would give us: ``` { "key": "00700916391", "message": { "subject": "Hey what's up?", "from": "example1@example.com", "to": "example2@example.com", "something": "something new" } } ``` Is there an Angular function that already does a deep merge that I am not aware of? If not is there a native way to do this in javascript recursively for n levels deep?