0

I have a JSON which looks like this:-

{
    "property" : value,
    "property" : value,
    "subProperty" : {
        "subProperty1" : {
            "subProperty1a" : {
                "property" : value,
                "property" : value
            },
            "subProperty1b" : {
                "property" : ["1", "2"],
                "property" : value
            },
            .....
        },
        "subProperty2" : {
            "subProperty2a" : {
                "property" : value,
                "property" : value
            },
            "subProperty2b" : {
                "property" : value,
                "property" : value
            },
            .....
        },
        "subProperty3" : {
            "subProperty3a" : {
                "property" : value,
                "property" : value
            },
            "subProperty3b" : {
                "property" : value,
                "property" : value
            },
            .....
        }
    }
}

This JSON can have any number of fields added later on in any position.What I want is when I add new fields, then I want to compare old JSON with new JSON. If any propert is missing, bind that property with new one.

Right now I am using following code to achieve this:-

    scope.tempObj = {};
    scope.findObjectByLabel = function(obj1, obj2, obj3){
                        for(var i in obj1)
                            {
                                obj3[i] = obj2[i];
                                if(obj2[i] == undefined)
                                {
                                    obj3[i] = obj1[i];
                                }
                                if(typeof(obj1[i]) == 'object')
                                {
                                    scope.findObjectByLabel(obj1[i], obj2[i],obj3[i]);
                                }
                            }
                            return obj3;        
                    }

scope.newJSON = scope.findObjectByLabel(scope.newJSON, scope.oldJSON ,scope.tempObj);

But the above code can only compare through one level. Can any one suggest me any improvement on the above code so that it can compare through entire JSON.

shreya gupta
  • 141
  • 12
  • Possible duplicate of [How to deep merge instead of shallow merge?](https://stackoverflow.com/questions/27936772/how-to-deep-merge-instead-of-shallow-merge) – xGeo Dec 06 '17 at 15:28

3 Answers3

1

Had the same problem , lodash came to the rescue.

https://lodash.com/docs/4.17.4

Look at merge & and deep equal (which is called just equal).

Usage example:

  //**********//
 // _.merge //
//**********//
 var object = {
  'a': [{ 'b': 2 }, { 'd': 4 }]
};

var other = {
  'a': [{ 'c': 3 }, { 'e': 5 }]
};

_.merge(object, other);
// => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }


  //**********//
 // _.equal //
//**********//
var object = { 'a': 1 };
var other = { 'a': 1 };

_.isEqual(object, other);
// => true

object === other;
// => false
Idan Beker
  • 353
  • 2
  • 9
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Luca Kiebel Dec 06 '17 at 15:10
1

You can use this _.merge polyfill from GitHub by @anvk.

function mergeDeep(out) {
  out = out || {};

  for (var i = 1, len = arguments.length; i < len; ++i) {
    var obj = arguments[i];

    if (!obj) {
      continue;
    }

    for (var key in obj) {
      if (!obj.hasOwnProperty(key)) {
        continue;
      }

      // based on https://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/
      if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
        out[key] = mergeDeep(out[key], obj[key]);
        continue;
      }

      out[key] = obj[key];
    }
  }

  return out;
};

var merged = mergeDeep({a: 1}, { b : { c: { d: { e: 12345}}}});  
console.dir(merged); // { a: 1, b: { c: { d: { e: 12345 } } } }
xGeo
  • 2,149
  • 2
  • 18
  • 39
0

To merge two object try like below.

function merge(oldObj, newObj){
   for (var prop in newObj) {
     if(typeof newObj[prop] === 'object'){
            merge(oldObj[prop], newObj[prop]);     
     }

     if(typeof newObj[prop] !== 'object')
        oldObj[prop] = newObj[prop];
    }
    return oldObj
}

console.log(merge(oldObj, newObj, oldObjTemp));

https://jsfiddle.net/8n244fmb/2/

To find the missing properties and values in multiple level.

var oldObj = {
     "name": "Bob Odenkirk",
     "title": "Software Engineer",
     "location": {
         "locality": "San Francisco",
         "region": "CA",
         "country": "United States"
     },
     "age": 62,
     "status": "Active"
};
var newObj = {
     "name": "Bob Odenkirk",
     "title": "Software Engineer",
     "location": {
         "locality": "San Francisco",
         "country": "United States"
     },
     "age": 62,
     "company": "Accenture"
};


var missingProps = {};

function getMissingProps(oldObj, newObj){
     for (var prop in oldObj) {
     if(newObj.hasOwnProperty(prop) && typeof oldObj[prop] === 'object')
       missingProps = getMissingProps(oldObj[prop], newObj[prop]);
     else if(!newObj.hasOwnProperty(prop))
         missingProps[prop] =  oldObj[prop] ;
   }

   return missingProps;
}

console.log(getMissingProps(oldObj, newObj));

https://jsfiddle.net/8n244fmb/

if you want complete missing Json props structure try this

var oldObj = oldObjTemp = {
     "name": "Bob Odenkirk",
     "title": "Software Engineer",
     "location": {
         "locality": "San Francisco",
         "region": "CA",
         "country": {"name" : "United States", "code":"US"}
     },
     "age": 62,
     "status": "Active"
};
var newObj = {
     "name": "Bob Odenkirk",
     "title": "Software Engineer",
     "location": {
         "locality": "San Francisco",
         "country": {"name" : "United States"}
     },
     "age": 62,
     "company": "Accenture"
};


var missingProps = {};

function getMissingProps(oldObj, newObj, oldObjTemp){
   for (var prop in oldObj) {
     if(newObj.hasOwnProperty(prop) && typeof oldObj[prop] === 'object'){
            getMissingProps(oldObj[prop], newObj[prop], oldObjTemp[prop]);     
     }
     else if(newObj.hasOwnProperty(prop)){
            delete oldObjTemp[prop];
     }
    }
}

getMissingProps(oldObj, newObj, oldObjTemp);

console.log(oldObjTemp);

https://jsfiddle.net/8n244fmb/1/