0

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?

FDavidov
  • 3,505
  • 6
  • 23
  • 59

1 Answers1

1

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.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks T.J. for your response. The way I build both objects is: (1) Build the **BASE** one with all the fields and their initial values, and then (2) build the **WORK** object as `@scope.Work_Object = JSON.parse(JSON.stringify(@scope.Base_Object))`. Following your response, I believe the answer to my question would be "YES", wouldn't it? – FDavidov Mar 29 '18 at 05:33
  • @FDavidov: Given that, I can't immediately think why it would be unreliable, but FWIW I still wouldn't do it. Again, a deep equality check is easy and will continue to work even when your code for creating the objects is inevitably modified over time. – T.J. Crowder Mar 29 '18 at 05:42
  • OK, got it (and marked your answer too). Still, since any future change would only be done to the **BASE** object (from which the **WORK** object is derived), I feel comfortable about this alternative. Many thanks!!!!! – FDavidov Mar 29 '18 at 06:06
  • @FDavidov: It's entirely your call. :-) – T.J. Crowder Mar 29 '18 at 06:25
  • 1
    I know... And still, you sometimes have to follow your guts ;-) – FDavidov Mar 29 '18 at 08:25
  • @FDavidov: Yup. :-) – T.J. Crowder Mar 29 '18 at 08:35