ngrx selectors with filters

The example is from ngrx.io

Assuming you have the selectValues selector and you want to filter the values making the code reusable.

import { select } from '@ngrx/store';
import { pipe } from 'rxjs';
import { filter } from 'rxjs/operators';

export const selectFilteredValues = pipe(
 select(selectValues),
 filter(val => val !== undefined)
);

store.pipe(selectFilteredValues).subscribe(/* .. */);

For that kind of scenario where I want to reuse part of a stream I create a function that accepts the store as a parameter and does some operations on it. The following is an example:

const selectMyState = (state) => state.myState;
export const getData = createSelector(selectMyState, state => state.data)
export const getDataWhenLoaded = (store) => {
    return store.select(getData)
        .filter(myState => myState.isLoaded);
};
...
getDataWhenLoaded(this.store).subscribe(...);

As far as using the last parameter of the createSelector function, you can depending on your need. In the documentation it mentions that the same state passed to the memoized selector created by createSelector will not recompute the projection. It will return the same value when invoked. I couldn't find documentation on this but through testing I noticed that if the projection results in the same value as the previous value then it will not be emitted if the subscription already received the previous value. Similar behavior to the rxjs operator distinctUntilChanged. I haven't had time to dig through their source code to understand where/how/why.

So in some cases you can put a filter in the projection parameter (last) for createSelector. Here is an example:

export const getActive = createSelector(selectMyData, state => state.data.filter(x => x.isActive));

Tags:

Angular

Ngrx