RxJS custom operators

Wojciech Trawiński
JavaScript everyday
2 min readJan 24, 2019

Undoubtedly, it’s a wide array of operators that makes the RxJS library extremely powerful utility in a developer’s tool belt. I’ve recently written several custom operators in order to reuse some repetitive combinations of operators in a nifty way. In this blog post, I will introduce you to the concept of custom RxJS operators and present exemplary implementations.

Identity operator

An RxJS operator is simply a function which takes a source observable as an input and returns a resulting stream. Therefore, the task of creating a custom RxJS operator comes down to writing a regular JavaScript (TypeScript) function. Let’s start with a basic identity operator which simply mirrors a source observable:

In the next step, let’s add some basic logic to a custom operator.

Logging operator

The following custom operator performs a side effect (logs values to the console) for each value of a source stream:

The resulting stream is composed on the basis of the source$ and altered by applying built-in operators via the pipe method.

Operator’s factory

In certain scenarios, it’s convenient to provide a context for a custom operator. You can accomplish it by defining a function which returns an operator. The factory’s arguments belong to the operator’s lexical scope:

You can simplify the return type annotation by making use of the MonoTypeOperatorFunction provided by the RxJS. In addition, the static pipe function enables to define an operator in a less verbose way:

If you seek for more RxJS-related tips, check this out.

Observer-unique lexical scope

An operator’s factory function is called once only at the moment of a stream definition. As a result, there’s a shared lexical scope for all observers:

If you want to get a unique lexical scope for each observer, you can make use of the defer function:

If you want to get to know how to solve the tapOnce task in a different way, take a look at one of my blog posts.

Real-life examples

firstTruthy operator:

evenMultiplied operator:

liveSearch operator:

Conclusions

Common RxJS operators’ combinations can be extracted into custom operators and reused in the future when implementing similar features. Generics enables proper type inference for emitted values further down in the pipe sequence.

Live example:

I hope you liked the post and learned something new 👍. If so, please give me some applause 👏

--

--