Javascript + AngularJS – Compare JSONs

I have a page within which there is a (well defined) number of inputs into which the user may enter data (i.e. text boxes, selects, etc.).

Whenever the user fills data and clicks on the SAVE button, a number of manipulations and checks need to take place before the actual SAVE process begins.

Now (and here is the question), whenever the user clicks on a “X” button to close the page, I want to check if data base changed at all (and prompt for confirmation if so).

I generate two objects with the full list of inputs:

  1. Initial values object holding the whole list of values BEFORE being presented to the user (@scope.Base_Object), and

  2. The whole list of inputs mapped to the inputs using ng-model (@scope.Work_Object).

Note: Both objects display identical structures which cannot change (i.e. no elements are added/removed).

So, I would expect that comparing JSON.stringify(@scope.Base_Object) against JSON.stringify(@scope.Work_Object) should tell me if anything was changed.

Is this method reliable enough?

Answer

Is this method reliable enough?

Only if the way the objects are created reliably adds the properties to the objects in the same order (or you define your own toJSON on the objects). JSON.stringify follows the property order that was defined in ES2015, which is sensitive to the order in which properties were created, and so two equivalent objects can have different JSON representations because the property order can be different:

var o1 = {a: 1, b: 2}; // Adds `a` before `b`
var o2 = {b: 2, a: 1}; // Adds `b` before `a`
var json1 = JSON.stringify(o1);
var json2 = JSON.stringify(o2);
console.log(json1);
console.log(json2);
console.log(json1 === json2); // false

A “deep” equals check is easy to do and more reliable. There are several questions and answers showing how to do that, such as this one.

Leave a Reply

Your email address will not be published. Required fields are marked *