NgRx selector filter null values

Viewed 5761

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?

3 Answers

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));
const isEqualOrNull = (state): boolean => state.a === state.b || state.b === null;



export const selectorNotNull = createSelector(
 youState,
 isEqualOrNull
);

You have to pass your state to the selector!

Related