-
-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Marking a property as "unique id" so modified items in array are considered updated
and not deleted+added
#14
Comments
To take in account my 2 needs I made a wrapper, this is not perfect because it just patches items and does not do more logic about In case someone is interested: // comparaison.ts
import { getListDiff as libraryGetListDiff } from '@donedeal0/superdiff';
// This is a custom implementation to fix specific needs (ref: https://github.com/DoneDeal0/superdiff/issues/14)
export const getListDiff: typeof libraryGetListDiff = (...args) => {
const results = libraryGetListDiff(...args);
let deletedDiffItems = results.diff.filter((diffItem) => {
return diffItem.status === 'deleted';
});
// Simulate `ignoreArrayOrder` as for some other of the library methods
// Also infer `updated` status for items
let tmpDiffItems: typeof deletedDiffItems = [];
for (const diffItem of results.diff) {
if (diffItem.status === 'moved') {
diffItem.status = 'equal';
} else if (diffItem.status === 'added') {
// If also deleted we change it to `updated` while removing it from the final `deleted` list
const correspondingDeletedItemIndex = deletedDiffItems.findIndex((deletedDiffItem) => {
return !!deletedDiffItem.value.id && deletedDiffItem.value.id === diffItem.value.id;
});
if (correspondingDeletedItemIndex !== -1) {
diffItem.status = 'updated';
deletedDiffItems.splice(correspondingDeletedItemIndex, 1);
}
} else if (diffItem.status === 'deleted') {
// We add remaining deleted items at the end
continue;
}
tmpDiffItems.push(diffItem);
}
results.diff = [...tmpDiffItems, ...deletedDiffItems];
return results;
}; and the associated tests: // comparaison.spec.ts
/**
* @jest-environment node
*/
import { getListDiff as libraryGetListDiff } from '@donedeal0/superdiff';
import { getListDiff } from './comparaison';
describe('getListDiff()', () => {
it('should recognize same objects based on id in the list', async () => {
const before = [
{ id: 1, myProp: 1 },
{ id: 2, myProp: 2 },
{ id: 3, myProp: 3 },
];
const after = [
{ id: 2, myProp: 222 },
{ id: 3, myProp: 3 },
{ id: 4, myProp: 4 },
];
const libraryDiffResult = libraryGetListDiff(before, after);
// The library will by default not recognized `updated` objects due to not considering stable IDs
expect(libraryDiffResult).toStrictEqual({
diff: [
{
indexDiff: null,
newIndex: null,
prevIndex: 0,
status: 'deleted',
value: {
id: 1,
myProp: 1,
},
},
{
indexDiff: null,
newIndex: null,
prevIndex: 1,
status: 'deleted',
value: {
id: 2,
myProp: 2,
},
},
{
indexDiff: null,
newIndex: 0,
prevIndex: null,
status: 'added',
value: {
id: 2,
myProp: 222,
},
},
{
indexDiff: -1,
newIndex: 1,
prevIndex: 2,
status: 'moved',
value: {
id: 3,
myProp: 3,
},
},
{
indexDiff: null,
newIndex: 2,
prevIndex: null,
status: 'added',
value: {
id: 4,
myProp: 4,
},
},
],
status: 'updated',
type: 'list',
});
const diffResult = getListDiff(before, after);
// Our own wrapper around the library function should fix those
expect(diffResult).toStrictEqual({
diff: [
{
indexDiff: null,
newIndex: 0,
prevIndex: null,
status: 'updated',
value: {
id: 2,
myProp: 222,
},
},
{
indexDiff: -1,
newIndex: 1,
prevIndex: 2,
status: 'equal',
value: {
id: 3,
myProp: 3,
},
},
{
indexDiff: null,
newIndex: 2,
prevIndex: null,
status: 'added',
value: {
id: 4,
myProp: 4,
},
},
{
indexDiff: null,
newIndex: null,
prevIndex: 0,
status: 'deleted',
value: {
id: 1,
myProp: 1,
},
},
],
status: 'updated',
type: 'list',
});
});
}); |
Salut Thomas, Thank you for using the lib! I understand your request. The behavior of I don't have much time to do this right now, but I'll look into it as soon as possible. This is a good suggestion. Thank you very much! |
The fix is out! Let me know if it works for you! If your company uses the project for commercial purposes, feel free to support it. Have a great weekend! |
Thanks @DoneDeal0 for your reactivity. I will try it out next week. It's not for commercial use but I appreciate your work, +1 for a coffee ☕ |
Thank you very much! |
@DoneDeal0 for your information, there is a mismatch between the release version of https://github.com/DoneDeal0/superdiff/releases/tag/v1.1.1 and https://www.npmjs.com/package/@donedeal0/superdiff?activeTab=versions. |
@DoneDeal0 just tried the release, with my test above your new version is telling the object with |
Please check this commit . It adds an option You're right, there was a mismatch between versions on npm. v1.1.1 is now out. Sorry for the inconvenience. |
@DoneDeal0 sorry if I have not been clear explaining the initial case. To give more context, when managing a datastore it's common to manage multiple items in a single endpoint input. I'm in the case where I get a CSV file regularly, and I need to synchronize it into my database. Depending on the previous version into the datastore and the new version you have to set, you will delete some in the database, update some (thanks to The I'm fine with staying with my workaround, I just wanted to clarify (and so, to me the current It's maybe too specific to the case of databases and I can hear it has no reason to be managed in this library, sorry for extending the thread 😄 EDIT: "too" specific because since an item can be both |
Hi @DoneDeal0 ,
I'm trying to compare arrays of objects but I would like the status
updated
to be triggered when some objects are modified. But for this to be, the library should define a property "stable" in the "before array" and into the "after array".The current state of the library:
would produce:
Whereas I expect the object with
id: 2
to beupdated
, nodeleted + added
. Did I miss something and it's already possible?A workaround I could try is to make a post-processor that looks at results, for similar
id
having both statusremoved
andadded
, keep just one of the two and setting the status toupdated
. Which would work, and would avoid modifying your library.Note aside: for other methods you implemented a
ignoreArrayOrder
. I think it could make sense to add it togetListDiff()
to getequal
instead ofmoved
(example forid: 3
here), but same here, the developer can just take into account those 2 statuses.Thank you,
The text was updated successfully, but these errors were encountered: