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.

selanac82
  • 2,920
  • 4
  • 27
  • 37

4 Answers4

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
klode
  • 10,821
  • 5
  • 34
  • 49
  • 6
    Note that angular.equals tests [identity, **not** equality](http://stackoverflow.com/questions/5447024/javascript-comparison-operators-identity-vs-equality). TL;DR: `angular.equals( { id: "12" }, { id: 12 } ) // is false` – bobjones Sep 25 '14 at 23:20
  • @bobjones angular.equals returns true based on identity OR deep equality, so your proposed example would return true. see the [angular.equals documentation](https://docs.angularjs.org/api/ng/function/angular.equals) , specifically Two objects or values are considered equivalent if at least one of the following is true – tommyTheHitMan Oct 31 '14 at 03:29
  • 5
    @tommyTheHitMan: bobjones example returns `false` because, based on identity, `"12"===12 // is false`. Just try it out. – klode Oct 31 '14 at 13:06
  • And if you need a diff object for tracking history for rollbacks, see this... https://gist.github.com/katowulf/6193808 – Mark Jan 27 '15 at 17:50
  • what if i need to find the difference between theese two, angular.equals only returns true or false, I need to have the difference if the answer is false. – Preena Khanuja Dec 17 '15 at 06:08
  • @PreenaKhanuja this is more a new question rather than a comment. I would suggest you ask a new question, you will also get more help. Look at this first it may answer your question http://stackoverflow.com/questions/264430/how-can-i-get-a-list-of-the-differences-between-two-javascript-object-graphs – klode Dec 17 '15 at 14:19
  • 4
    A quick note: angular.equals() ignores all properties beginning with $, and all properties whose values are functions, when both arguments are objects. – mellis481 May 23 '16 at 19:58
  • I came here searching for object copying for keeping track of state. So on a related note, there is also `angular.copy()` for obtaining decoupled `obj1` and `obj2`. – AdamAL Nov 07 '16 at 15:06
27

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

JSON.stringify(obj1) == JSON.stringify(obj2);
tymeJV
  • 103,943
  • 14
  • 161
  • 157
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);
Jeremy Moritz
  • 13,864
  • 7
  • 39
  • 43
KM.
  • 51
  • 1
  • 1
  • 4
    From the Angular documentation: "During a property comparison, properties of function type and properties with names that begin with $ are ignored." https://docs.angularjs.org/api/ng/function/angular.equals – sonicwizard Mar 30 '15 at 20:50
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)
DanteTheSmith
  • 2,937
  • 1
  • 16
  • 31