7 things you might not know about RxJS

Wojciech Trawiński
JavaScript everyday
4 min readAug 2, 2020

In this blog post, I will share with you several tips concerning the RxJS library. I reckon that they are not so well-known, therefore it will be beneficial to spend some time reading the post.

Teardown Logic

Despite the RxJS library contains a great number of built-in observable factories (e.g. from, of, etc.), you can create your own stream with the aid of the Observable class.

Let’s take a look at the custom implementation of the interval function:

A well-known fact is that you can return a callback function from the function passed as the first argument to the Observable constructor. It will be called when you unsubscribe from the stream, which makes it a perfect place to perform a teardown logic. In the above example, it’s responsible for clearing the interval. However, there are situations when the only thing you need to do within the callback function is to unsubscribe from some inner observables:

In such scenarios, you can simply return the Subscription instance (line 12):

It’s feasible, since the function passed to the Observable constructor may return an object of TeardownLogic type, which can be either Function or Unsubscribable.

iif

If you want to conditionally subscribe to one of the two streams, you can make use of the iif function. It takes up to three arguments, namely the predicate function and the two streams, one of which will be subscribed to based on the return value of the first parameter. However, it’s worth to mention that expressions passed as the second and third arguments will be evaluated eagerly which is different from how ternary operator works:

If you want to take advantage of lazy evaluation and call a single function only, you need to make use of the defer function:

tap

The tap operator is a well-known tool to perform side effects for values emitted by an observable:

However, a not so well-known fact is that you can perform side effects for all types of notifications (next, error, complete), e.g. you can do it for the complete one:

finalize

The finalize operator is another one which allows you to perform side effects. It’s common to believe that the callback function, passed to the operator, will be executed upon an error or complete notification from a source stream. A typical usage would be to toggle a loading flag, whether an http request has succeeded or failed:

However, to be more precise, the callback function will be invoked when there is a final value in the stream in question. The value may show up not only due to a complete or error notification from the source stream, but also as a result of unsubscribing prior to the source observable completion or error occurrence:

Please notice that the finalize’s callback has been called, whereas the complete’s one has not.

mapTo

If you want to project a value emitted by a stream, an obvious solution is to use the map operator. However, there are situations when you do not need a source value to compute the resulting one. For example, you may want to map a click event to a boolean value. In such scenarios, you can take advantage of the mapTo operator:

It’s worth to stress that the projected value is the same for all the values emitted by a source stream and it’s computed at the moment of an observable’s definition:

There are also corresponding operators with ‘To’ suffix for switchMap, concatMap and mergeMap operators.

distinct

If you want to get an array of unique values in JavaScript, you may convert it to a Set instance. When working with streams of data, you can accomplish a similar goal with the aid of the distinct operator:

The values are compared by reference, hence in order to make it work as expected with an array of objects, you can pass a key selector function as the operator’s first argument:

As a result, there will be only a single value with a given id in the resulting stream.

pipe

There will be a moment in you career when you decide to write your own custom RxJS operator. It’s as simple as creating a function which takes an input observable and returns an output stream:

However, if your custom operator only composes several built-in ones, you can take advantage of the static pipe function in order to get a little bit less verbose syntax:

Live example:

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

--

--