How can i merge two nested javascript objects?

I am currently using the code below:

function mergeFaculty(json){
    tempList = $.extend(tempList, json);
    console.log(JSON.stringify(tempList));
}

However, it does not work.

the objects are the following:

{"modulos":{"id":"1","name":" Usuarios","paginas":{"id":"1","name":" Listado Usuarios","facultades":{"id":"1","name":" ver"}}}}

{"modulos":{"id":"1","name":" Usuarios","paginas":{"id":"1","name":" Listado Usuarios","facultades":{"id":"2","name":" editar"}}}}

any idea why it doesn't work?

Answers 1

  • First of all I think that you have a problem with your object structure, since your facultades key is an object and not an array. You should use an array if you wish to hold both facultades objects after the extension.

    That said, it seems $.extend even overrides arrays, meaning it will choose the array of the latest object passed as an argument to this function. So this isn't good for you, as the array will still hold one of the 2 objects in facultades.

    To correctly merge arrays we could use the $.merge function, but that is only good for arrays. Since you have a JSON object in hand this won't work.

    As a result, what I did was simply write my own recursive code to utilize both features: a deep copy extend function and a merge function in case of an array.

    Hope you find this useful to achieve what you wanted (explanations in comments):

    var tempList = {"modulos":{"id":"1","name":" Usuarios","paginas":{"id":"1","name":" Listado Usuarios","facultades":[{"id":"1","name":" ver"}]}}}
    var secondObject = {"modulos":{"id":"1","name":" Usuarios","paginas":{"id":"1","name":" Listado Usuarios","facultades":[{"id":"2","name":" editar"}]}}}
    
    // Deep extend recursive function
    function deepExtend(firstObject, secondObject, tempObject) {
        tempObject = typeof tempObject === "undefined" ? {} : tempObject;
    
        // Flattens multidimensional arrays
        function flatten(array) {
            if (array.length) {
                return array.reduce(function(prev, cur) {
                    return prev.concat(cur)
                })
            }
        }
        // Iterates over both object, extends and merges them
        function iterateObjects(object1, object2) {
            var keys = Object.keys(object1);
            for (var i = 0; i < keys.length; i++) {
                var key = keys[i];
                var firstObjectValue = object1[key];
                var secondObjectValue = object2[key];
    
                if (firstObjectValue.constructor === Array) {
                    tempObject[key] = []
                    // Flatten arrays from each object
                    flatten(firstObjectValue) ? tempObject[key].push(flatten(firstObjectValue)) : null;
                    flatten(secondObjectValue) ? tempObject[key].push(flatten(secondObjectValue)) : null;
    
                } else if (firstObjectValue.constructor === Object) {
                    tempObject[key] = deepExtend(firstObjectValue, secondObjectValue, {})
                } else {
                    tempObject[key] = object2[key] || object1[key]
                }
            }
            return tempObject;
        }
        // Extend in both orders to find unique keys that appear only in one object
        tempObject = iterateObjects(firstObject, secondObject, tempObject);
        tempObject = iterateObjects(secondObject, firstObject, tempObject);
    
        return tempObject;
    }
    
    
    function mergeFaculty(json) {
        //tempList = $.merge(  tempList, json);
        tempList = deepExtend(tempList, json);
        console.log(JSON.stringify(tempList));
    }
    
    mergeFaculty(secondObject);


Related Articles