1import { transform, isEqual, isObject } from 'lodash';
2
3/**
4 * Deep diff between two object, using lodash
5 * @param {Object} object Object compared
6 * @param {Object} base Object to compare with
7 * @return {Object} Return a new object who represent the diff
8 */
9function difference(object, base) {
10 return transform(object, (result, value, key) => {
11 if (!isEqual(value, base[key])) {
12 result[key] = isObject(value) && isObject(base[key]) ? difference(value, base[key]) : value;
13 }
14 });
15}
1const { inspect } = require('util')
2const transform = require('lodash.transform')
3const isEqual = require('lodash.isequal')
4const isArray = require('lodash.isarray')
5const isObject = require('lodash.isobject')
6
7/**
8 * Find difference between two objects
9 * @param {object} origObj - Source object to compare newObj against
10 * @param {object} newObj - New object with potential changes
11 * @return {object} differences
12 */
13function difference(origObj, newObj) {
14 function changes(newObj, origObj) {
15 let arrayIndexCounter = 0
16 return transform(newObj, function (result, value, key) {
17 if (!isEqual(value, origObj[key])) {
18 let resultKey = isArray(origObj) ? arrayIndexCounter++ : key
19 result[resultKey] = (isObject(value) && isObject(origObj[key])) ? changes(value, origObj[key]) : value
20 }
21 })
22 }
23 return changes(newObj, origObj)
24}
25
26/* Usage */
27
28const originalObject = {
29 foo: 'bar',
30 baz: 'fizz',
31 cool: true,
32 what: {
33 one: 'one',
34 two: 'two'
35 },
36 wow: {
37 deep: {
38 key: ['a', 'b', 'c'],
39 values: '123'
40 }
41 },
42 array: ['lol', 'hi', 'there']
43}
44
45const newObject = {
46 foo: 'bar',
47 baz: 'fizz',
48 cool: false, // <-- diff
49 what: {
50 one: 'one',
51 two: 'twox' // <-- diff
52 },
53 wow: {
54 deep: {
55 key: ['x', 'y', 'c'], // <-- diff
56 values: '098' // <-- diff
57 }
58 },
59 array: ['lol', 'hi', 'difference'] // <-- diff
60}
61
62// Get the Diff!
63const diff = difference(originalObject, newObject)
64
65console.log(inspect(diff, {showHidden: false, depth: null, colors: true}))
66/* result:
67{
68 cool: false,
69 what: { two: 'twox' },
70 wow: { deep: { key: [ 'x', 'y' ], values: '098' } },
71 array: [ 'difference' ]
72}
73*/
74
75if (diff.cool) {
76 console.log('Coolness changed to', diff.cool)
77}