Skip to content

Entity sorting after updates is not stable #2297

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

Closed
markerikson opened this issue Apr 28, 2022 · 7 comments · Fixed by #2464
Closed

Entity sorting after updates is not stable #2297

markerikson opened this issue Apr 28, 2022 · 7 comments · Fixed by #2464
Milestone

Comments

@markerikson
Copy link
Collaborator

Per https://www.reddit.com/r/reduxjs/comments/ud58hg/sortcomparer_in_rtk_switches_the_ordering_of/ :

I'm using createEntityAdapter with sortComparer to sort some entities based on a timestamp for when they were last updated. If the entities haven't been updated yet, this timestamp is null. There are many cases of these null timestamps in my data.

I'm displaying these sorted entities in a table, where I can also make edits that will modify the entity object by dispatching an action, which uses the updateOne entity adapter method. Note that this edit has no impact on the timestamp used for sorting.

My problem is: if I edit an entity which has a matching timestamp as other entities (this happens often in the case of null timestamps), that item will suddenly be re-ordered to appear at the bottom of my table.

It seems like this happens because the sortComparer function returns 0 since the comparison is equal, so the order is then based on the ordering of entities in my slice. But because the entity was updated, redux re-orders the entity in the slice to now be at the bottom (which I can see happening using the redux dev tools). This means that any time I change an entity that has an equal sort comparison, it will now be automatically reordered to be last.

Is there any way around this? It seems crazy to me that I can't rely on a consistent ordering for items that have an equal comparison.

My analysis:

Hmm. We ultimately just call array.sort() with whatever sorting comparator you provided.

However, given that it's doing Object.values(entities), the order of items in that array is going to be based on insertion order into that object, I think. Given that the update logic is implemented by deleting the existing item ID from state.entities before it gets re-added later, I can see how that might result in an updated item technically getting added later.

@markerikson markerikson added this to the 1.9 milestone May 22, 2022
@lightDer
Copy link

I encountered the same problem. Please see this example.
When update timestamp of items, the item will be sorted to the last one, although the order doesn't change.

@markerikson
Copy link
Collaborator Author

This should actually be fixed now in #2464 and will be out in whatever the next patch or minor release is.

@Reishei
Copy link

Reishei commented Dec 5, 2022

i encountered same problem as well.

Before i'm using and it gives me an error.
createEntityAdapter({
selectId: (doc) => doc.id,
sortComparer: (a, b) => a.creation.localeCompare(b.creation)
})

After:
what works for me is this: sorted from recent date.
createEntityAdapter({
selectId: (doc) => doc.id,
sortComparer: (a, b) => b.creation - a.creation
})

@markerikson
Copy link
Collaborator Author

@Moglie2817 : what version of RTK are you using? This was fixed in 1.8.3.

@Reishei
Copy link

Reishei commented Dec 5, 2022

@markerikson : i'm using version 1.8.1.
Maybe i need to upgrade. Thanks for the info.

@Mac-DevOSYandex
Copy link

I get squigglies under date but it works! When will this be fixed or am I doing s/thing wrong!?!

const postsAdapter = createEntityAdapter({
sortComparer: (a, b) => b.date.localeCompare(a.date)
});

Property 'date' does not exist on type '{ id: EntityId; }'.ts(2339)
⚠ Error (TS2339) |
Property date does not exist on type .

@EskiMojo14
Copy link
Collaborator

@Mac-DevOSYandex you haven't provided an entity type.

const postsAdapter = createEntityAdapter<Post>({
sortComparer: (a, b) => b.date.localeCompare(a.date)
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants