benjamine / jsondiffpatch

Diff & patch JavaScript objects
MIT License
4.83k stars 472 forks source link

incorrect delta when an array has objects itself #12

Closed dheerajaggarwal closed 11 years ago

dheerajaggarwal commented 11 years ago

Hi, From the first look, I liked your library very much. But now, I am in trouble, trying the following code:

var json1 = {"a":[{"b":"c"}]};
var json2 = {"a":[{"b":"c"}]};

//json1 and json2 are both identical
var delta = jsondiffpatch.diff(json1, json2);

console.log(JSON.stringify(delta));

And I am getting the following output:

{"a":{"0":[{"b":"c"}],"_t":"a","_0":[{"b":"c"},0,0]}}

Two questions:

  1. is the above output correct? In my opinion, there should be no delta.
  2. How to read the delta? I didn't find any documentation to read delta. Please let me know if I am missing something. (what is _t stands for in delta?)

Any help is appreciated.

benjamine commented 11 years ago

Hi, answering your questions:

1 - Yes, this is expected, the diff is saying {"b":"c"} got removed from index 0, and {"b":"c"} got added at index 0. The reason is when comparting array items, jsondiffpatch can't guess two objects are the same unless you provide a hash function (or they are equal by ref, ie. the same object).

Check this is an example taken from README:

jsondiffpatch.config.objectHash = function(obj) { obj.id || JSON.stringify(obj); };

Realize this function will only be executed once per object (the result gets cached) and only when objects being compared are not equal by reference (the same object, or a value type). using JSON.stringify might be a bit more costy than a recursive comparison of object fields (which you could easily write), but might be good enough for most cases.

Note the DEMO page uses a very similar objectHash function and you can test no diff is produced there using the data in your example.

2 - I apologize, there's no docs on reading the delta yet, but they are pretty simple, here's the basics:

dheerajaggarwal commented 11 years ago

Hi Benjamine, Thanks a lot for your answers. Yes, it is working after adding objecthash. :)

I have some more questions, will get back to you soon.

benjamine commented 11 years ago

Ok, no problem, closing this one then.