83

Is it possible to do a "deep" comparison of two object in Angular? What I would like to do is compare each key/value pair. For example:

Object 1

{
   key1: "value1",
   key2: "value2",
   key3: "value3"
}

Object 2

{
   key1: "value1",
   key2: "newvalue",
   key3: "value3" 
}

What I need is for the comparison to fail since only one of the key/value pairs is diffent. In other words ALL of the key/value pairs must match exactly or else failure. Is this something already built into Angular. I'm sure I could write my own service if I really needed to, but I was hoping it was already built in. Similar to angular.equals.

4 Answers 4

208

To compare two objects you can use:

angular.equals(obj1, obj2)

It does a deep comparison and does not depend on the order of the keys See AngularJS DOCS and a little Demo

var obj1 = {
  key1: "value1",
  key2: "value2",
  key3: {a: "aa", b: "bb"}
}

var obj2 = {
  key2: "value2",
  key1: "value1",
  key3: {a: "aa", b: "bb"}
}

angular.equals(obj1, obj2) //<--- would return true
Sign up to request clarification or add additional context in comments.

8 Comments

Note that angular.equals tests identity, not equality. TL;DR: angular.equals( { id: "12" }, { id: 12 } ) // is false
@bobjones angular.equals returns true based on identity OR deep equality, so your proposed example would return true. see the angular.equals documentation , specifically Two objects or values are considered equivalent if at least one of the following is true
@tommyTheHitMan: bobjones example returns false because, based on identity, "12"===12 // is false. Just try it out.
And if you need a diff object for tracking history for rollbacks, see this... gist.github.com/katowulf/6193808
A quick note: angular.equals() ignores all properties beginning with $, and all properties whose values are functions, when both arguments are objects.
|
27

Assuming that the order is the same in both objects, just stringify them both and compare!

JSON.stringify(obj1) == JSON.stringify(obj2);

5 Comments

angular.equals(obj1,obj2) should also work. It does not depend from the keys order and it is deep (it is called recursively) code.angularjs.org/1.2.0/docs/api/angular.equals
That would be a very bad assumption!
angular.toJson would also remove the $$hashKeys
This does not work if the order of properties is different. So JSON.stringify({a:1, b:1}) === JSON.stringify({b:1, a:1}) is false.
@PeterB feels like I mentioned that somewhere in the answer...
5

Bit late on this thread. angular.equals does deep check, however does anyone know that why its behave differently if one of the member contain "$" in prefix ?

You can try this Demo with following input

var obj3 = {}
obj3.a=  "b";
obj3.b={};
obj3.b.$c =true;

var obj4 = {}
obj4.a=  "b";
obj4.b={};
obj4.b.$c =true;

angular.equals(obj3,obj4);

1 Comment

From the Angular documentation: "During a property comparison, properties of function type and properties with names that begin with $ are ignored." docs.angularjs.org/api/ng/function/angular.equals
2

I know it's kinda late answer but I just lost about half an hour debugging cause of this, It might save someone some time.

BE MINDFUL, If you use angular.equals() on objects that have property obj.$something (property name starts with $) those properties will get ignored in comparison.

Example:

var obj1 = {
  $key0: "A",
  key1: "value1",
  key2: "value2",
  key3: {a: "aa", b: "bb"}
}

var obj2 = {
  $key0: "B"
  key2: "value2",
  key1: "value1",
  key3: {a: "aa", b: "bb"}
}

angular.equals(obj1, obj2) //<--- would return TRUE (despite it's not true)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.