How can I find out why two objects do not compare equal with angular.equals?

I am using the following AngularJS code:

if (angular.equals(rowData, $scope.grid.backup[i])) {
   console.log('equal')
}

Please note that AngularJS has an equals function that compares each element inside the object.

The two objects look equal when I debug but Angular does not agree. I just cannot see what is not equal. Is there some other way I can do a comparison?

Answer

The doc for angular.equals() says:

Two objects or values are considered equivalent if at least one of the following is true:

Both objects or values pass === comparison.

Both objects or values are of the same type and all of their properties are equal by comparing them with angular.equals.

Both values are NaN. (In JavaScript, NaN ==> NaN => false. But we consider two NaN as equal)

Both values represent the same regular expression (In JavasScript, /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual representation matches).

So, if you’re getting a false for .equals(), then we can conclude the following:

  1. The two are not the same object so they don’t pass ===
  2. Both values are not NaN (you are presumably working with objects anyway)
  3. Both values are not the same regex

So, that only leaves the 2nd item in the documentation which means that either the objects are not the same type or some of their properties are not the same. For anyone to help you further on what exactly is different between them, we’d have to see the actual objects or the code that creates them.

If you have the non-minimized version of angular installed in your page, you could also just step through your call to angular.equals() and see which step in the code it is finding the difference.

Or, if there are a lot of properties or a lot of objects so stepping in the debugger is difficult, you could write your own little debug routine to tell you which property was different. That would look something like this:

function compareObjects(s, t) {
    if (typeof s !== typeof t) {
        console.log("two objects not the same type");
        return;
    }
    if (typeof s !== "object") {
        console.log('arguments are not typeof === "object"');
        return;
    }
    for (var prop in s) {
        if (s.hasOwnProperty(prop)) {
            if (t.hasOwnProperty(prop)) {
                if (!angular.equals(s[prop], t[prop])) {
                    console.log("property " + prop + " does not match");
                }
            } else {
                console.log("second object does not have property " + prop);
            }
        }
    }
    // now verify that t doesn't have any properties 
    // that are missing from s
    for (prop in t) {
        if (t.hasOwnProperty(prop)) {
            if (!s.hasOwnProperty(prop)) {
                console.log("first object does not have property " + prop);
            }
        }
    }
}


// then call this function on your two objects
// and then look in the debug console to see what it reports
compareObjects(rowData, $scope.grid.backup[i]);

Leave a Reply

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