Create your account

Already have an account? Login here

Note: By joining, you will receive periodic emails from Coursetro. You can unsubscribe from these emails.

Create account

RxJS Operators Tutorial - Learn How to Transform Observables

By Gary simon - Mar 29, 2018

  • Note: This tutorial is a part our free comprehensive RxJS Tutorial

In the previous tutorials, we discovered how to create Observables (along with special observables called Subjects) and subscribe to them.

That's only part of RxJS, though. RxJS offers an extensive collection of operators. There are well over a 100+ operators in RxJS that you can use with observables.

In this tutorial, we're going to...

  • More closely look at what operators are..
  • Learn how to read the official RxJS documentation to understand the many operators
  • Use a few operators so we can get some muscle memory going..

So, let's get started!

If you prefer watching a video..

Be sure to Subscribe to the Official Coursetro Youtube Channel for more videos.

What is an RxJS Operator?

Operators are simply methods that you can use on Observables (and Subjects) that allow you to change the original observable in some manner and return a new observable. These operators do not change the existing Observable; they simply modify it and return a new one. Operators are known as pure functions, which are functions that do not modify the variables outside of its scope.

You can also create a sequence of operators that will modify an incoming observable, output a new observable, and so on..

There are also two types of operators:

  • Static Operators
    These operators are usually used to create observables. You will find these mainly under the creation operators.

  • Instance Operators
    These are methods on observable instances. These account for the majority of RxJS operators that are used.

Understanding Marble Diagrams

The official documentation uses marble diagrams to help you understand how a given operator modifies an observable.

Here's the official explanation of how a marble diagram works:

In other words, at the top you have the original observable along with their events emitted from time that goes left to right. In the middle it states the name of the operator, and then the newly transformed observable is at the bottom.

Using an Operator

If you take a look at the official documentation for categories of operators, you would see that there are several categories to choose from:

  • Creation
  • Transformation
  • Filtering
  • Combination
  • Multicasting
  • Error Handling
  • Utility
  • Conditional & Boolean
  • Mathematical and Aggregate

Depending on what you want to do with the incoming observable, you would choose an operator from one of these categories.

Let's say that we wanted to merge two separate observables into one. This merge operator is combining two observables, so it falls under the Combination category. 

Here's what the marble diagram looks like for merge:

Two observables up top, and a new one at the bottom that merges them. Let's give it a go!

In your /src/code.ts file, specify the following:

import { Observable } from "rxjs/Observable";
import { merge } from 'rxjs/observable/merge';

var observable = Observable.create((observer:any) => {
    observer.next('Hey guys!')
})

var observable2 = Observable.create((observer:any) => {
    observer.next('How is it going?')
})

// We're using our merge operator here:
var newObs = merge(observable, observable2);

newObs.subscribe((x:any) => addItem(x));

// Our handy function for showing the values:
function addItem(val:any) {
    var node = document.createElement("li");
    var textnode = document.createTextNode(val);
    node.appendChild(textnode);
    document.getElementById("output").appendChild(node);
}

You can see that we have 2 observables observable and observable2. Then, we use the merge operator to merge both observables, and then we subscribe to the new observable.

Simple!

Getting More Practice

Let's try a few more operator examples to help with our observable/operator muscle memory!

Map Operator

Map is one operator that you see a lot when working within Angular and API's. It simply allows you to take the input values and make some type of transformation.

So, if we wanted to multiply numbers, append a string to the end of events, or make all of the results capital, we could use .map:

import { Observable } from "rxjs/Observable";
import "rxjs/add/operator/map";

    Observable.create((observer:any) => {
        observer.next('Hey guys!')
    })
    .map((val:any) => val.toUpperCase())
    .subscribe((x:any) => addItem(x));

Note: Above is a less verbose way of achieving the same results from the previous example:

The result:

Pluck Operator 

Let's say your observable emits an array of objects with multiple properties, but you only need a single property?  Well, you can pluck that property from the original observable, and return a new observable with just that property:

So, try the following code with the pluck operator:

import { from } from "rxjs/Observable/from";
import "rxjs/add/operator/pluck";

    from([
            { first: 'Gary', last: 'Simon', age: '34'},
            { first: 'Jane', last: 'Simon', age: '34'},
            { first: 'John', last: 'Simon', age: '34'},
    ])
    .pluck('first')
    .subscribe((x:any) => addItem(x));

Note: Notice how instead of using the static operator of Create to create our observable as in the previous examples, we're using a different static operator of .from()

The result:

SkipUntil Operator

This operator is a little more complex than the previous examples. It allows you to start emitting events from one observable, based on when a second observable begins emitting events.

Try updating the code to the following:

import { Observable } from "rxjs/Observable";
import { Subject } from "rxjs/Subject";
import { interval } from "rxjs/Observable/interval";
import "rxjs/add/operator/skipUntil";

var observable1 = Observable.create((data:any) => {
    var i = 1
    setInterval(() => {
        data.next(i++)
    }, 1000)
})

var observable2 = new Subject;

setTimeout(() => {
    observable2.next('Hey!')
}, 3000)

var newObs = observable1.skipUntil(observable2)

newObs.subscribe((x:any) => addItem(x));

Our first observable observable1 is just a regular observable that uses setInterval() to emit an integer that increases by 1 every second.

Our second observable is a Subject (a special observable that we covered in the previous tutorial) that we simply define but don't immediately emit any values.

We use setTimeout() to create a 3 second delay before emitting a value from our second observable.

Then, we use skipUntil() to create a third observable.

The result:

We only see 3 because we've skipped 1 and 2 because they didn't occur after the second observable began emitting events.

Conclusion

As you can see with the amount and variety of RxJS operators, you have an immense amount of flexibility when working with observables.

At this point, you should be feeling quite comfortable with RxJS!

  • Note: This tutorial is a part our free comprehensive RxJS Tutorial

Share this post




Say something about this awesome post!