cosmicanant / recursive-diff Goto Github PK
View Code? Open in Web Editor NEWA JavaScript library to find diff between two JavaScript Objects. Support for Array, Number, Date and other primitive data types.
License: MIT License
A JavaScript library to find diff between two JavaScript Objects. Support for Array, Number, Date and other primitive data types.
License: MIT License
Let's assume I have the following objects:
const initialVal = {
v: {
data: [
{},
],
},
}
const changedVal = {
v: {
data: [
{
blabla: 3,
},
],
},
}
const delta = getDiff(initialVal, changedVal);
const diff = applyDiff(initialVal, delta);
console.log(delta);
console.log(diff);
The output of this would be:
[ { op: 'add', path: [ 'v', 'data', 0, 'blabla' ], val: 3 } ]
{ v: { data: [ [Object] ] } }
It this the wanted output [Object]
?
Should't it be:
{ v: { data: [ {blabla: 3} ] } }
I'm wondering if you had seen this module: https://github.com/flitbit/diff . It looks like it has very similar algorithm (looks like array changes are taken item by item, rather than attempting to find a more minimal diff - same as flitbit's diff does). Figured you might want to check it out.
Errors thrown as literals do not include stack trace. Used error objects, used more verbose error messages and tested. Pull Request: #4
Hi, im using this library to get the diff when a record changes and then register the log with the differences.
Maybe could be helpful add a ignore parameter to set fields that we don't want to be analyzed. In my case, i don't want to diff the field updatedAt, so i need to remove this field before call getDiff.
I'm having an issue regarding visitorCallbackFn
. Seems like it's not called if the diff is on the first level of the jsons...
I suspect it's because of this line. Any reason for this check? I'd change this code to be something like this:
if (i !== length - 1) {
val = val[key];
if (visitorCallback) {
visitorCallback(val);
}
} else {
val[key] = value;
if (i === length -1 && length === 1 && visitorCallback) {
visitorCallback(val);
}
}
In my use case I would like to call the visitor in the first level, which happens to be also the last...
I'll demonstrate the issue by a failing test:
In jsonDiff.js
:
import { applyDiff, getDiff } from 'recursive-diff';
export const getNewObjWithDiff = (originalObj, newObj) => {
const callback = (ob) => {
if (ob instanceof Object) {
ob.isVisited = true;
}
};
const delta = getDiff(originalObj, newObj);
return applyDiff({ ...originalObj, ...newObj }, delta, callback);
};
In jsonDiff.spec.js
:
import { getNewObjWithDiff } from './jsonDiff';
const json = { '/hello': {} };
const newJson = {
'/hello': { leaf: true },
'/drafts': {
leaf: true,
},
};
describe('jsonDiff', () => {
it('should return new json with diff inside', () => {
expect(getNewObjWithDiff(json, newJson)).toEqual({
'/hello': {
leaf: true,
isVisited: true,
},
'/drafts': {
leaf: true,
isVisited: true,
},
});
});
});
This currently fails with the following returned output (missing isVisited
in "/drafts"):
{
"/drafts": {
"leaf": true
},
"/hello": {
"isVisited": true,
"leaf": true
}
}
Here is a sample code
Hi there,
I'm comparing Date
objects with this package. Apparently, Date
objects are objects themselves therefore typeof new Date() === 'object'
is true. This causes the package to recurse on Date
objects rather than comparing them. Also, this causes the package to not detect changes on Date
objects.
Repro:
import diff from 'recursive-diff'; // version 0.1.4
const obj1 = {
date1: new Date('2019-01-01'),
date2: new Date('2019-02-01')
};
const obj2 = {
date1: new Date('2019-02-01'),
date2: new Date('2019-03-01')
};
const delta = diff.getDiff(obj1, obj2); // {}
As far as I could follow the code, there should be a distinct handling for Date
objects here as it just checks for typeof val1 === 'object'
or val1 !== val2
.
Maybe I can try to file a pull request sometime soon but I'm not too sure.
Title says it all. Hoping someone can take a look. Thanks.
https://codepen.io/KevinBatdorf/pen/601484f72bf013bcc851e5fa39ba4c75?editors=1010
I would expect the fresh
variable to be { number: 0, history: [] }
recursive-diff.js is broken, recursive-diff is right
It seems that when there are nested objects the original value is modified when calling applyDiff
import { applyDiff, getDiff } from 'recursive-diff';
const origVal = { foo: { a: 1, b: 2, c: 3 } };
const newVal = { foo: { a: 11, b: 22, d: 44 } };
const delta = getDiff(origVal, newVal);
console.log('before', { origVal, newVal });
/* --- output
before {
origVal: { foo: { a: 1, b: 2, c: 3 } },
newVal: { foo: { a: 11, b: 22, d: 44 } }
}
*/
const finalVal = applyDiff(origVal, delta);
console.log('after', { origVal, newVal, finalVal });
/* --- output
after {
origVal: { foo: { a: 11, b: 22, d: 44 } },
newVal: { foo: { a: 11, b: 22, d: 44 } },
finalVal: { foo: { a: 11, b: 22, d: 44 } }
}
*/
Hi, Im planning to use your library within a project but without npm. I want to use it from the source code but not really sure how I can add the license and other copyrights. How would you recommend ?
I propose to add
npm i recursive-diff
to README.md
Hey there I hope you are doing great,
I was wondering if there is a away to ignore fields that have nullish values when diffing?
The use-case could be having, let's say, some value as undefined
in the source object, but empty string or empty array for the same field in target (transformer may have converted undefined values to empty/nullish) and I would like not to consider these as a change for specific property, but ignore it from changes
object.
Thank you in advance and have a great day ๐
Consider the objects below
var initialVal = [
{
name: "Sam",
title: "Marketing manager",
email: "[email protected]"
},
{
name: "Abel",
title: "Director",
email: "[email protected]"
}
];
var changedVal = [
{ name: "Abel Smith", title: "Director", email: "[email protected]" }
];
console.log(getDiff(initialVal, changedVal));
This is the output I get
0: Object
op: "update"
path: Array(2)
val: "Abel Smith"
oldVal: "Sam"
1: Object
op: "update"
path: Array(2)
val: "Director"
oldVal: "Marketing manager"
2: Object
op: "update"
path: Array(2)
val: "[email protected]"
oldVal: "[email protected]"
3: Object
op: "delete"
path: Array(1)
0: 1
oldVal: Object
name: "Abel"
title: "Director"
email: "[email protected]"
The object that got deleted is
{
name: "Sam",
title: "Marketing manager",
email: "[email protected]"
},
But it's not being captured.
This happens because we are preserving the array order.
Can we add an additional flag which when set to true checks whether the element was in the array or not regardless of the order?
Hi, I think that would be helpful put in the rdiffResult object a property like "oldValue" when the operation is update.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.