RxJS Pt.2 - Basic operators

RxJS Pt.2 - Basic operators

Simple operators

In RxJS each emitted item can be piped through a set of operators. The operators can transform, filter or process the item. And since observables arrive over time, we can also perform a delay, timeout or a time based operation An RxJS operator is a function that transforms and manipulates items emitted from an observable. We apply operators in sequence using the observable's pipe() method.

Lets talk about the following code

of(2, 4, 6, 8)
  .pipe(
    map(item=> item * 2),
    tap(item => console.log(item)),
    take(3)
  ).subscribe(item => console.log(item));

Each operator takes an observable as an input, and creates and returns an output observable. And that observable becomes the input in the sequence and so on. And this is how observables work. There are at the moment 114 RxJS built-in operators. You can find them all in the official documentation.

Now lets dive into these operators.

map operator

map(item=> item * 2)

The map operators transforms or changes each emitted item, as defined by a function we provide. In this case we take all the items and multiply it by two. Map can not change the number of emitted items. For each item exactly one mapped item is emitted out. You can use map() to make changes to each emitted item. RxJS marble diagram shows that the map operator applies immediately

map is a transformation operator

tap operator

tap(item => console.log(item))

tap() Taps into the emission without affecting the items You can use tap for debugging, or performing actions outside of the flow of data (side effects). You will want tap as your best friend as you learn RxJS and should be the first thing you add to your pipeline if you are not getting the results you expect. RxJS marble diagram shows that the tap operator applies immediately.

tap is a utility operator

take operator

take() emites a specified number of item

take(3)

In the code above we emit three items. You can use take for taking a specified number of items and limiting unlimited observables. RxJS marble diagram shows that the tap operator applies immediately.

take is a filtering operator

map operator internals

export function map(fn) {
  return (input) => 
    new Observable(observer => {
      return input.subscribe({
        next: value => observer.next(fn(value)),
        error: err => observer.error(err),
        complete: () => observer.complete
      })
    })
}

To better understand how an operator works let's look at the internals of the RxJS map operator. The actual map operator implementatio nis a bit more complex, but it demonstrates its basic functionality. Notice that an internally an operator is just a function. It takes an input observable, and creates a new output observable. It subscribes to the input observable and passes an observer, with next(), error() and complete() methods. When an item is emitted, the next method executes. It transforms the item as specified in the provided function and emits the transformed item to the output observable. If an error occurs, it emits an error notification. If the input observable completes, it emits a complete notification. Now this is important, because RxJS is opensource, so you can write own RxJS operators. You can see other all the operators in their GitHub repo.

Did you find this article valuable?

Support Renátó Bogár by becoming a sponsor. Any amount is appreciated!