Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NgRx selector filter null values

Tags:

angular

rxjs

ngrx

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?

like image 444
fodma1 Avatar asked Sep 05 '18 16:09

fodma1


People also ask

Are NgRx selectors Memoized?

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.

Is NgRx synchronous?

Selectors are synchronous by default, meaning that they emit the value immediately when subscribed to, and on every state change.


2 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.

like image 128
timdeschryver Avatar answered Sep 29 '22 04:09

timdeschryver


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));
like image 28
fodma1 Avatar answered Sep 29 '22 04:09

fodma1