DEV Community

Stas Kohut
Stas Kohut

Posted on

RxJS Operators decision table

I like this joke yet I think it's obsolete.
I remember myself 4 years ago trying to comprehend all the concepts behind reactive programming, learning ways to write my streams and manipulate them using operators. It wasn't easy besides you had to keep up with all new changes (and there're a few of them). But today RxJS is a mature toolchain with a lot of learning materials, the amount of effort the team puts into making the library more accessible for common folks like me is truly impressive.

Yet it's still a common opinion that RxJS is not very friendly for newbies. Besides core concepts of reactive programming (that are not specific to RxJS), the number of operators available for a user might be intimidating.
As I stated above, the maintainers' team did and doing a great job simplifying and improving the API. And luckily we don't need to remember all of them as a tiny portion is actually needed for everyday use.

Still, you can find yourself a bit lost thinking of what operator should I use in certain cases. Don't worry the docs got you covered, it contains a super useful operator decision tree util https://rxjs.dev/operator-decision-tree. Answering simple question about your intentions with the stream it can suggest the most fitting operator for your case.

It's great, but I prefer the table view of the same tree. And unsurprisingly there's such a table https://xgrommx.github.io/rx-book/content/which_operator_do_i_use/index.html, but there's another "but" – it's a bit outdated thus I present you the up-to-date (at the time of writing this post) version of the same table:

Creation operators

I want to create a new sequence using custom logic Observable (class)
that works like a for-loop generate
that throws an error throwError
that completes EMPTY (const)
that never does anything NEVER (const)
from an event fromEvent
that uses custom functions to add and remove event handlers fromEventPattern
over the values in an array of object key/values pairs
over values in a numeric range range
over the values in an iterable, a Promise, array or array-like object from
over arguments of
that emits values on a timer interval
with an optional initial delay timer
decided at subscribe-time based on a boolean condition iif
using custom logic defer
that depends on a resource using
I want to combine multiple sequences and only receive values from the sequence that yields a value first race
and be notified when all of them have finished forkJoin
and output the values from all of them merge
in order reusing the latest value when unchanged combineLatest
using each value only once zip
by subscribing to each in order when the previous sequence completes concat
regardless of whether the previous sequence completes or errors onErrorResumeNext

Stream operators (ex instance operators)

Using an existing sequence I want to change each value map
I want to pull a property off each value pluck
I want to be notified of values without affecting them tap
I want to include values based on custom logic filter
from the start of the sequence take
based on custom logic takeWhile
from the end of the sequence takeLast
until another sequence emits a value or completes takeUntil
I want to ignore values altogether ignoreElements
from the start of the sequence skip
based on custom logic skipWhile
from the end of the sequence skipLast
until another sequence emits a value skipUntil
that have the same value as the previous distinctUntilChanged
based on object by key distinctUntilKeyChanged
by selector distinct
that occur too frequently throttle
based on duration throttleTime
by emitting the first value in each time window debounce
based on due time debounceTime
by emitting the last value in each time window audit
based on due time auditTime
I want to compute using custom logic and only output the final value reduce
and output the values as they are calculated scan
and output observables as they are calculated mergeScan
I want to wrap its messages with metadata that describes each message materialize
that includes the time past since the last value timeInterval
that includes a timestamp timestamp
after a period of inactivity I want to throw an error timeout
I want to switch to another sequence timeoutWith
I want ensure there is only one value and throw an error if there are more or less than one value single
I want to only take the first value and throw an error if there are no values first
within a time period sample
based on period sampleTime
I want to only take the last value and error if there are no values last
I want to know how many values it contains count
by all of its values every
I want to delay messages by a specific amount of time delay
based on custom logic delayWhen
I want to group the values until the sequence completes toArray
using custom logic as arrays buffer
as sequences window
in batches of a particular size as arrays bufferCount
as sequences windowCount
based on time as arrays bufferTime
as sequences windowTime
based on observable as arrays bufferWhen
as sequences windowWhen
based on a key until the sequence completes groupBy
I want to start a new sequence for each value and emit the values from all sequences in parallel mergeMap
and emit the values from each sequence in order concatMap
and cancel the previous sequence when a new value arrives switchMap
and recursively start a new sequence for each new value expand
I want to combine it with another And be notified when both have completed forkJoin
I want to share a subscription between multiple subscribers using a specific subject implementation multicast
and start it as soon as first subscriber arrives share
and start it manually or imperatively publish
and supply the last value to future subscribers publishLast
and replay a default or the latest value to future subscribers publishBehavior
and replay n number of values to future subscribers publishReplay
when an error occurs I want to re-subscribe retry
based on custom logic retryWhen
I want to start a new sequence catchError
when it completes I want to re-subscribe repeat
I want to start a new sequence concat
when it completes or errors I want to start a new sequence onErrorResumeNext
when it completes, errors or unsubscribes I want to execute a function finalize
I want to change the scheduler that routes calls to subscribe subscribeOn
messages observeOn
Using two sequences I want to decide which to receive values from based on which one has values first race
I want to determine if their values are equal sequenceEqual
I want to combine their values only when the first sequence emits, using the latest value from each withLatestFrom
in order reusing the latest value when unchanged combineLatest
using each value only once zip
I want to include values from both merge

If you're new to RxJS be sure to check out Eran's beginner guide post

Keep hacking my dudes 😉

Latest comments (0)