-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Ability to change sortComparer in the ngrx/entity #898
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
Comments
Isn't the sort a calculated property? Shouldn't it be then implemented in a selector? Pseudo: // State
{
selectedSort: {
name: 'byName',
order: 'asc'
}
}
const getSortedKeysAsArray = createSelector(
getAll,
getSelectedSort,
( entityArray, sortProps ) => {
// point compareFn to sort function generator taking order as a parameter
switch( sortProps.name ) {
//...
}
// don't mess with actual entity array
return entityArray.slice()
// sort
.sort( compareFn(sortProps.order) )
// collect only ids in order
.map( entity => entity.id );
});
const getSortedArray = createSelector(
getEntities,
getSortedKeysAsArray,
( entities, sortedKeys ) => {
return sortProps.map( id => entities[id]);
}) |
Um… I think we shouldn’t use selectors this way. Selectors are executed multiple times per each action. And we are returning new instances of the array, so all subscriptions will be executed even if no values has been changed. Of course there is a better work-around for my problem. We can recreate the EntityAdapter in the reducer whenever the sorting method is changed. In my opinion there should be an easier solution for that, and it doesn't look hard to implement. |
A selector is not recomputed unless one of its arguments changes. You have accidental mutable state if one action leads to multiple calls to one selector. |
I don’t like putting logic into selectors. It feels just wrong. And sorting the entire table after each change doesn’t look performance friendly. |
Guys, I am starting to learn about entities and wonder about the sortComparer feature. In the example, I see
In my app, I want to sort my entities dynamically by a dropdown in the UI: Time Created ASC/DESC, Entity Name A-Z, and Entity Name Z-A. Can the sortComparer function be an observable that it will react to my dropdown change and then automatically reorder the entities for me? If not, I think I will try out what @MattiJarvinen-BA has suggested |
@dereklin selectors are meant to be pure and synchronous, so if you need to do some advanced sorting that reacts to some other change, you would have a selector that listens for a dropdown change value, combine it with your entities and return a newly sorted list. There's nothing wrong with doing this sorting at the component level also before consuming it also. |
@brandonroberts Thanks for the reply. For now, I think I have to implement a custom selector. It seems like the sortComparer function only takes in two arguments: entityA and entityB. It will be nice if it has the store snapshot as the third argument. Then I can implement a more comprehensive sorting algorithm. This will allow me to just use the selectAll selector provided by ngrx/entity, without having to create a custom selector. |
@dereklin what are you exactly trying to do? |
@tdeschryver @MattiJarvinen-BA 's snippet is a custom selector, right? I think that will work. I guess what I am saying is that if the sortComparer function has the state snapshot as a param, then I don't need to implement a custom selector. Instead, I can change of the order of my entities based on other properties that are outside of the entities but are inside of the state. |
exactly what I was looking for and I think it's a very common use case. |
Was reading what akita is about and found this: https://netbasal.gitbook.io/akita/entity-store/entity-query/sort-by
Seems like they have thought about this. From what I can tell, Akita uses services heavily and basically move actions and reducers inside services; which reminds me of what ngrx-data does for entities. With the integration between ngrx-data and nrgx, will we see a bigger role for services inside ngrx, thus reducing the need to write actions and reducers? |
@dereklin if you want to use services with NgRx, take a look at the Facades pattern. |
@dereklin Something to keep in mind about NgRx Entity's sortComparer interface is that by having it be immutable we can optimize operations like If we passed Using selectors on the other hand means that your application will only change the sort method when the target property in your state changes. Selectors plus an unsorted state adapter would be the best optimization strategy for your application and wouldn't require us to de-optimize parts of the sorted state adapter. As for your last question there will be no increased emphasis on services in NgRx in the future. Pure functions will always be our default. 👍 |
Hello! I am using NGRX with Entity. Now I have to sort my entities, but I can not find a single example. Can you give a working example to do this? |
I used a different approach. I created an object in the reducer.ts file which holds the sort fields, those fields are being updated whenever the user changes the sort field/order. This object is being imported in the entity-metadata.ts file and is being used by the sortComparer function. The example below is for user entity, the object is usersSelectedSort and it holds key and order fields which are used for sort by the sortComparer. user.reducer.ts:
app.entity-metadata.ts:
for listening to sort event I placed an event handler in the template via matSortChange. user.component.html:
and in my component I dispatch the sort action and afterwards refresh the view. unfortunately I haven't found a good way to refresh the view other then replacing the items with addAllToCache. user.component.ts:
|
I would like to have a ability to change
sortComparer
without recreating the whole collection.I'm submitting a...
What is the current behavior?
sortComparer can be defined only once, while calling the
createEntityAdapter
. Right now we have just a read-only access to this function.Expected behavior:
A new method defined in the
EntityState<T>
, let's call itsetSortComparer
. This function should return a new state with collection sorted using different comparer.The text was updated successfully, but these errors were encountered: