Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter undefined from RxJS Observable

Is there a specific idiom or utility used to filter undefined from RxJS observables? This code has the behavior I want:

obs.pipe(filter(x => x !== undefined))

Some alternatives are

obs.pipe(filter(x => x)) // for all falsy values

obs.pipe(filter(Boolean)) // for falsy variables using Boolean ctor
like image 976
djechlin Avatar asked Sep 18 '19 19:09

djechlin


People also ask

What is filter in RxJS?

RxJS filter() operator is a filtering operator used to filter items emitted by the source observable according to the predicate function. It only emits those values that satisfy a specified predicate. The RxJS filter() operator is like the well-known Array Array .

Which operator will filter the values from source Observable based on the predicate function given?

This operator will filter the values from source Observable based on the predicate function given.

What is pipe operator in RxJS?

A Pipeable Operator is a function that takes an Observable as its input and returns another Observable. It is a pure operation: the previous Observable stays unmodified. A Pipeable Operator is essentially a pure function which takes one Observable as input and generates another Observable as output.


1 Answers

Strictly speaking, using filter alone to remove undefined values doesn't do everything that you need. It filters out the undefined values, but does not change the type to indicate that undefined is no longer a possible value.

In the example:

const obs = new Subject<string | undefined>;
const stringObs = obs.pipe(filter(x => x !== undefined))

the stringObs observable still has the type Observable<string | undefined>.

To get round this problem, you need to use:

const stringObs = obs.pipe(filter(x => x !== undefined) as OperatorFunction<string | undefined, string>)

This is only really an issue if you use strict null checks, but if you do (and arguably you should) then creating a custom operator suddenly makes a lot more sense! Something like

function filterNullish<T>(): UnaryFunction<Observable<T | null | undefined>, Observable<T>> {
  return pipe(
    filter(x => x != null) as OperatorFunction<T | null |  undefined, T>
  );
}

does the job.

You can then use:

const stringObs = obs.pipe(filterNullish())

and the type of stringObs will be Observable<string>. I was quite impressed that Typescript manages to infer the type of T correctly.

like image 117
Simon Williams Avatar answered Sep 17 '22 07:09

Simon Williams