JavaScript
Posted By Sebastian

Getting Started With RxJS – Part 2: Subscriptions


Subscribe On YouTube

Code

Part 1: Setting Up The Development Environment & Creating Observables
Part 2: Subscriptions
Part 3: Hot And Cold Observables

RxJS (Reactive Extensions for JavaScript) is a library for transforming, composing, and querying streams of data. It brings the concept of reactive programming to the web. The library allows you to work with asynchronous data streams with ease.

In the first part of this Getting Started With RxJS series you’ve learned how to set up the development and get started with RxJS by creating your first Observable and subscribing to the notification emitted by the Observable.

In this second part of this series we’re going to take a closer look at subscriptions. You’ll learn how to cancel subscriptions, work with multiple subscriptions on the same observable, and dealing with child subscriptions.


If you like CodingTheSmartWay, then consider supporting us via Patreon. With your help we’re able to release developer tutorial more often. Thanks a lot!


Extending The Sample Application

We’re going to use the sample application we’ve started to build in the first part of this series. This application will be extended in the following steps. Let’s first do some adaptions to the HTML user interface in file index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>RxJS Demo</title>

    <style>
        body { font-family: 'Arial'; background: lightgray }
        button { padding: 15px; }
        ul { list-style-type: none; padding: 20px; }
        li { padding: 15px; background: lightcoral; margin-bottom: 10px; }
        .row { display: flex; }
        .column { flex: 50%; }
    </style>
</head>
<body>
    <h1>RxJS Demo</h1>
    <div class="row">
        <div class="column">
            <center>
                <button id="unsubscribeBtn1">Unsubscribe</button>
            </center>
            <ul id="list1"></ul>
        </div>
        <div class="column">
            <center>
                <button id="unsubscribeBtn2">Unsubscribe</button>
            </center>
            <ul id="list2"></ul>
        </div>
    </div>
    <script src="/bundle.js"></script>
</body>
</html>

The user interface is extended to contain a two-column layout (by using CSS Flexbox layout). Each column is containing a button to unsubscribe and a list (with identifier list1 and list2) to output Observable notifications.

With that extension made in index.html, we’re able to focus on the TypeScript implementation in src/index.ts once again.

First we’re going to adapt the helper function logItem to accept an additional parameter, so that we’re able to control in which column the output should be inserted into:

function logItem(val:any, column:any) {
    var node = document.createElement("li");
    var textnode = document.createTextNode(val);
    node.appendChild(textnode);
    if (column == 2) {
        document.getElementById("list2").appendChild(node); 
    } else if (column == 1) {
        document.getElementById("list1").appendChild(node);
    }  
}

Next we’re adapting the creation of the Observable to emit notifications in an interval of 5 seconds:

var observable1 = Observable.create((observer:any) => {
    observer.next('Observable One is alive!');
    setInterval(() => {
        observer.next('Observable One');
    }, 5000);
});

Subscribing to this Observable is done via the following code:

var subscription1 = observable1.subscribe(
    (x:any) => logItem(x, 1)
);

Unsubscribing

Next we need to register an event handler function for the Unsubscribe button of the first column:

document.getElementById('unsubscribeBtn1').addEventListener('click', () => {
    subscription1.unsubscribe();
});

Every time the user clicks on this button we’re calling the unsubscribe method for our subscription. After having called this method we’re no longer receiving notifications.

Let’s try out what we’ve built so far. Start the development server via

$ npm run start

You should be able to see the following output in the browser:


In the left column every five seconds a new notification from the Observable is printed out. If you now click on the button Unsubscribe you’ll notice that no more notification are added because the subscription is no longer active.

Working With Multiple Subscriptions

Let’s create a second subscription for the existing Observable and display the results in the right column:

var subscription2 = observable1.subscribe(
    (x:any) => logItem(x, 2)
);

Now the result in the browser should look similar to what you can see in the following screenshot:

The notifications are printed out simultaneously every five seconds in both columns.

Now let’s create a second Observable in our application:

var observable2 = Observable.create((observer: any) => {
    observer.next('Observer Two is alive!');
    setInterval(() => {
        observer.next('Observable Two');
    }, 2500);
});

And change the second subscription as well to subscribe to notification of this new Observable:

var subscription2 = observable2.subscribe(
    (x:any) => logItem(x, 2)
);

In contrast to the first Observable (which is emitting notifications every five second) the second observable is emitting notification every 2,5 seconds. Thus you know will be able to see notifications appearing on the right side every 2,5 seconds and notifications appearing on the left side column every five seconds.

Child Subscriptions

Let’s introduce a second button for the right columns in index.html:

<button id="addSubscriptionBtn">Add Subscription One</button>

Sebastian Eschweiler
By clicking on that button the second subscription is added to the first subscription as a child subscription by using the add method. There a new click event handler function is added:

document.getElementById('addSubscriptionBtn').addEventListener('click', () => {
    subscription2.add(subscription1);
});

After having created the child subscription try to click on one of the Unsubscribe buttons. You’ll then notice that no more notifications are reported (not via subscription 1 and not via subscription 2). Both subscriptions are cancelled at once.

In the following listing you can see the complete source code of file index.ts once again:

import { Observable } from 'rxjs';

var observable1 = Observable.create((observer:any) => {
    observer.next('Observable One is alive!');
    setInterval(() => {
        observer.next('Observable One');
    }, 5000);
});

var observable2 = Observable.create((observer: any) => {
    observer.next('Observer Two is alive!');
    setInterval(() => {
        observer.next('Observable Two');
    }, 2500);
});

var subscription1 = observable1.subscribe(
    (x:any) => logItem(x, 1)
);

var subscription2 = observable1.subscribe(
    (x:any) => logItem(x, 2)
);

document.getElementById('unsubscribeBtn1').addEventListener('click', () => {
    subscription1.unsubscribe();
});

document.getElementById('unsubscribeBtn2').addEventListener('click', () => {
    subscription2.unsubscribe();
});

document.getElementById('addSubscriptionBtn').addEventListener('click', () => {
    subscription2.add(subscription1);
});

function logItem(val:any, column:any) {
    var node = document.createElement("li");
    var textnode = document.createTextNode(val);
    node.appendChild(textnode);
    if (column == 2) {
        document.getElementById("list2").appendChild(node); 
    } else if (column == 1) {
        document.getElementById("list1").appendChild(node);
    }  
}

What’s Next

In the upcoming third part of the Getting Started With RxJS series we’re focusing on Hot and Cold Observables and explore the differences in practice.

ONLINE COURSE: RxJS 6 In Practice

Check out the great RxJS 6 In Practice course with hundreds of students already enrolled:

RxJS 6 In Practice

  • Learn numerous RxJs Operators, learn all RxJs and Reactive Programming core concepts via Practical Examples
  • Learn the RxJs library via Practical Examples
  • Understand in detail the core notions of Reactive Programming

  • Become familiar with an extended subset of RxJs Operators

  • Learn how to design and build Applications in Reactive style

Go To Course


Using and writing about best practices and latest technologies in web design & development is my passion.