ngrx parameter to select function

5.2k views Asked by At

Is there a way to pass parameters to ngrx select functions?

Following is my use case:

I am maintaining list of comments in store.

I wrote one component to represent one comment. So, one CommentComponent knows the id of the component object

Each comment will have properties like likedBy, reportedBy, ...etc In UI, I am showing all the components using *ngFor

Now I want my CommentComponent to subscribe only to one comment object by using id of the component.

Right now I am subscribing to all the comments in a top level component, and passing each comment to the CommentCompoent as an input.

Current approach is not clean because angular change detection strategy (even if I use onPush) has to render DOM for all the comments even though only one comment changes.

Appreciate any suggestions where I can pass comment id to a selector function so that each CommentComponent can subscribe to only one comment.

Thanks in advance, Sudhakar

3

There are 3 answers

0
timdeschryver On BEST ANSWER

As of NgRx 6.1, you can use a selector with props.

export const getCount = () =>   
  createSelector(     
    (state, props) => state.counter[props.id],     
    (counter, props) => counter * props.multiply
);

For more info and different ways, check out my article NgRx: Parameterized selectors

4
Jaya Krishna On

Yes, you can pass parameters to the ngrx selector and you can do that in this way

from the component side

this.store.select(getComments(user_id));

from the selector side

export const getComments = (user_id) => createSelector(
  getData,
  (store) => store.comments 
);
0
A Hutch On

@CularBytes I've been working through a similar issue with using this approach with testing for awhile now and think i've found a way to make it work.

With the selector of

export const getItemsByProperty = (property: string, value: any) => createSelector(getAllItems, (items: ItemObj[]) => items.filter((item) => item[property] == value));

and where

export const getAllItems = createSelector(getState, (state) => selectAll(state.items));

in my components unit test file i override the selector for the getItemsByProperty's underlying selector call, getAllItems, with data and then expect the filtered data in my tests. If what you want to return changes, then just update the result of getAllItems.