Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to addOne item at the beginning of collection in ngrx/entity

I started using ngrx/entity package, where I can manage store by adapter. There is addOne method I'd like to use, but it adds item to the end of collection. I wanna add one at the beginning. Could you please help me with that? How to add item at the beginning with EntityAdapter.

How I create entity adapter:

export const adapter: EntityAdapter<AssetTreeNode> = createEntityAdapter({
  selectId: (model: AssetTreeNode) => model.Id
});

Reducer looks like that:

export function reducer(state: AssetListState = initialState, action: AssetListAction) {
  switch (action.type) {
    (...)
    case ASSET_LIST_ADD_ITEM:
      let assetToAdd: AssetTreeNode = Object.assign({} as AssetTreeNode, 
        action.payload.asset, 
        { Id: action.payload.createdAssetId });
      return adapter.addOne(assetToAdd, state); <--- I wanna add here at the end.
    (...)
    default:
      return state;
  }
}
like image 694
magos Avatar asked Aug 24 '18 06:08

magos


3 Answers

The only way to change this behavior would be to use the sortComparer when you create the adapter - docs.

export const adapter: EntityAdapter<User> = createEntityAdapter<User>({
  sortComparer: (a: User, b: User) => a.name.localeCompare(b.name),
});
like image 89
timdeschryver Avatar answered Sep 25 '22 13:09

timdeschryver


There is no proper way provided by @ngrx/entity team. One of the answer mentions to use sort-comparator. But i believe using sort-comparator is not the right way to go. Suppose there is two click actions and in one action we need to append item below and in other action on top. here we will run into the same problem again.

I had run into the same issue and my solution to the problem is to reconstruct the list when we want the item on top of the list.

To add at the top of entity list

const { selectAll } = myAdapter.getSelectors();
...
...
on(MyActions.addItem, (state, { item }) =>{
    return myAdapter.setAll([item ,...selectAll(state)], { ...state})
}),

To add at the bottom of entity list

on(MyActions.addItem, (state, { item}) =>{
   return myAdapter.addOne(item, state)
}),
like image 20
Rameez Rami Avatar answered Sep 25 '22 13:09

Rameez Rami


Maybe you could place the item at the begining and replace the list

on(addAsset, (state, { payload }) => {
  const currentList = Object.values(state.entities);
  const newList = [payload, ...currentList];
  return adapter.setAll(newList, state);
});
like image 35
Pedro Lescano Avatar answered Sep 24 '22 13:09

Pedro Lescano