Our web app loads values in the NgRx store which are set to null in the initial state. I'm looking for a way to nicely filter non-null values because I keep seeing in components
this.myValue = this.store.pipe(
select(mySelector),
filter(notNull),
);
// where
const notNull = (data) => data !== null;
And I consider this code duplication, it'd be great to handle this at selector level. But I'm also open to other solutions.
One thing I tried is a custom createSelector
:
import {createSelector, createSelectorFactory, defaultMemoize} from '@ngrx/store';
const isEqualOrNull = (a: any, b: any): boolean =>
a === b || b === null;
const createSelectorNotNull = createSelectorFactory((projectionFn) =>
defaultMemoize(projectionFn, isEqualOrNull));
Unfortunately, this solution would not handle initial null
values, only further ones.
Is there a nice solution to this seemingly frequent problem?
Benefits of using selectors There is a number of benefits: Memoization. First of all, selectors created by createSelector are memoized, meaning that they won't be called unnecessarily unless the data in the store has changed. This provides an important performance boost.
Selectors are synchronous by default, meaning that they emit the value immediately when subscribed to, and on every state change.
I don't think this is possible, because as you already mentioned the first time it won't use the compare functions you provide and just executes and returns the result.
To avoid code duplication you could create your own pipeable operator.
Eventually, I came to the same conclusion as @timdeschrver.
import { select } from '@ngrx/store';
import { notNull } from './utils';
import { filter } from 'rxjs/operators';
export const selectNotNull = (selector, ...args) => (source$) =>
select(selector, ...args)(source$)
.pipe(filter(notNull));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With