-1

I have two objects, I want to list changes between both as described below:

Currently I'm getting following output

current value || new value
title : Object 1 || title : Object 1 UPDATED
description : Object 1 Description || description : Object 1 Description UPDATED

Currently my code works for root level comparison(as highlighted above). But I am looking for comparisons on deep/nested child-level differences.

My output should look something like below

current value || new value
title : Object 1 || title : Object 1 UPDATED
description : Object 1 Description || description : Object 1 Description UPDATED
releations.tools[0].title: my first tool || releations.tools[0].title: my first tool UPDATED
relations.tools[0].types[1].name : test2 || DELETED
relations.training[0].description: training Description || relations.training[0].description: training Description UPDATED
relations.training[0].trainingTypes[1].name : in-person || DELETED

My current code

function diffObjects(obj1, obj2) {
    let res = [];
    let objKeysArray = _.keys(obj2) || [];
    if (!obj1 || !obj2) {
        return res;
    }
    if (objKeysArray.length === 0) {
       return res;
    }
    _(objKeysArray).forEach((key) => {
        console.log(obj1[key], obj2[key]);
        if (_.isArray(obj1[key]) && _.isArray(obj2[key])) {

        } else if (_.isObject(obj1[key]) && _.isObject(obj2[key])) {

        } else if (!_.isEqual(obj1[key], obj2[key])) {
            let change1 = `${key} : ${obj1[key]}`;
            let change2 = `${key} : ${obj2[key]}`;
            res.push({
                currentVal: change1,
                newVal: change2
            });
        }
    });
    return _.flattenDeep(res);
}

I have created a fiddle for above code here: JSFiddle Link : https://jsfiddle.net/vr0pgemj/

I have already referenced these posts:
Deep comparison of objects/arrays
Javascript Deep Comparison

But they only give me TRUE or FALSE results and not the differences I am looking for.

Community
  • 1
  • 1
R G
  • 3
  • 8
  • There is no such thing as a "JSON object". I guess you mean a "JavaScript object". –  May 30 '16 at 18:31

1 Answers1

0

I made a working fork of your fiddle here with ECMAscript6 syntax.

Here is an embedded version as well:

(function() {
  'use strict';

  function diffObj(obj1, obj2, ref) {
    var prefix = ref || '';
    var res = [];

    if (!_.isUndefined(obj1) && _.isUndefined(obj2)) {
      res.push({
        currentVal: prefix + ' : ' + JSON.stringify(obj1),
        newVal: 'DELETED'
      });
    } else if (_.isUndefined(obj1) && !_.isUndefined(obj2)) {
      res.push({
        currentVal: 'DELETED',
        newVal: prefix + ' : ' + JSON.stringify(obj2)
      });
    }

    if (_.isUndefined(obj1) || _.isUndefined(obj2)) {
      return _.flattenDeep(res);
    }

    var keys = _.uniq(_.keys(obj1).concat(_.keys(obj2)));


    _(keys).forEach(function(key) {
      var value1 = obj1[key];
      var value2 = obj2[key];

      if (!_.isUndefined(value1) && _.isUndefined(value2)) {
        res.push({
          currentVal: prefix + key + ' : ' + value1,
          newVal: 'DELETED'
        });
      } else if (_.isUndefined(value1) && !_.isUndefined(value2)) {
        res.push({
          currentVal: 'DELETED',
          newVal: prefix + key + ' : ' + value2
        });
      } else if (_.isArray(value1) && _.isArray(value2)) {
        var entries = Math.max(value1.length, value2.length);
        for (var i = 0; i < entries; i++) {
          res.push(diffObj(value1[i], value2[i], prefix + key + '[' + i + '].'));
        }
      } else if (_.isObject(value1) && _.isObject(value2)) {
        res.push(diffObj(value1, value2, prefix + key + '.'));
      } else if (!_.isEqual(value1, value2)) {
        res.push({
          currentVal: prefix + key + ' : ' + value1,
          newVal: prefix + key + ' : ' + value2
        });
      }
    });

    return _.flattenDeep(res);
  }

  var json1 = {
    "id": 1,
    "title": "Object 1",
    "description": "Object 1 Description",
    "test": "foo bar",
    "relations": {
      "tools": [{
        "id": 2,
        "title": "my first tool",
        "description": "tools description",
        "types": [{
          "id": 123,
          "name": "test"
        }, {
          "id": 111,
          "name": "test2"
        }]
      }],
      "training": [{
        "id": 3,
        "title": "Test training",
        "description": "training Description",
        "trainingTypes": [{
          "id": 1,
          "name": "online"
        }, {
          "id": 2,
          "name": "in-person"
        }, {
          "id": 3,
          "name": "boot camp"
        }]
      }]
    }
  };
  var json2 = {
    "id": 1,
    "title": "Object 1 UPDATED",
    "description": "Object 1 Description UPDATED",
    "relations": {
      "tools": [{
        "id": 2,
        "title": "my first tool UPDATED",
        "description": "tools description",
        "types": [{
          "id": 123,
          "name": "test"
        }]
      }],
      "training": [{
        "id": 3,
        "title": "Test training",
        "description": "training Description UPDATED",
        "trainingTypes": [{
          "id": 1,
          "name": "online"
        }, {
          "id": 3,
          "name": "boot camp"
        }]
      }]
    }
  };
  var res = diffObj(json1, json2);
  res = res.map(function(d) {
    return '<tr><td>' + d.currentVal + '</td><td>' + d.newVal + '</td></tr>';
  });
  $('#tableResult > tbody').append(res);
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>
<table id="tableResult" class="table table-hover table-striped">
  <thead>
    <tr>
      <th>
        current
      </th>
      <th>
        new
      </th>
    </tr>
  </thead>
  <tbody>

  </tbody>
</table>
George Karanikas
  • 1,244
  • 1
  • 12
  • 38