Click here to Skip to main content
15,879,184 members
Articles / Web Development / HTML

A Note on RxJS Subjects

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
2 Jul 2017CPOL4 min read 9.3K   34   2   2
This is a note on RxJS subjects.

Introduction

This is a note on RxJS subjects.

Background

Element based programming has been increasingly popular in web applications. Regardless if you use React or Angular, or if you choose not to use any of the frameworks, an RxJS subject can be useful to communicate among different programming units.

An RxJS subject is a JavaScript object that broadcasts notifications to all the subscribers from any publishers.

Besides giving some simple examples, this note talks about how to keep an RxJS subject alive after an error is broadcasted through the subject.

The attached is a Maven project with three small examples. But you do not need to have Java to run it. All the examples are in the HTML files. You can host the HTML files in any web server.

A Basic Example on RxJS

Let us take a look at the "rxjs-1-basic-example.html" first. An RxJS subject is pretty easy to use. In order to save my effort to describe how an RxJS subject is used, I will recommend you to take a brief look at the RxJS document before looking at the example.

HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>rxjs-1-basic-example.html</title>
<link rel="stylesheet" type="text/css" href="styles/app.css">
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.1/Rx.min.js"></script>
    
<script type="text/javascript">
        
    let ClockSubject = new Rx.BehaviorSubject('');
        
    let SubscribeToClockSubject = function(eId) {
        let element = document.getElementById(eId);
            
        ClockSubject.subscribe(
            function(time) {
                element.innerHTML = time;
            },
            function(error) {
                element.innerHTML = error;
            }
        );
    };
        
    window.onload = function() {
        SubscribeToClockSubject('clock1');
        SubscribeToClockSubject('clock2');
        SubscribeToClockSubject('clock3');
            
        let getTime = function() {
            let d = new Date();
                
            return d.toLocaleDateString() + ' ' + d.toLocaleTimeString();
        };
            
        // Set a timer to update the subject
        setInterval(function() {
            ClockSubject.next(getTime());
            
        }, 1000);
        
        // Set the subject at page load
        ClockSubject.next(getTime());
    };
    
</script>
    
</head>
<body>
<div><a href="index.html">Back ...</a></div>
<div id="clock1" class="clock"></div>
<div id="clock2" class="clock"></div>
<div id="clock3" class="clock"></div>
</body>
</html>

In this example, I added three "divs" in the HTML. The goal is to display the current time in all the "divs". A "setInterval" callback is used to get the current time for every second. It is sent to all the subscribers through an RxJS subject named "ClockSubject".

  • A publisher can publish a notification to all the subscribers through the "next()" method on the subject;
  • A publisher can publish an error to all the subscribers through the "error()" method on the subject (We will see an example for "error()" in the second example).

When we subscribe to the RxJS object, we can pass two callback functions to the "subscribe()" method.

  • The first function is the notification callback function. When a notification is published, this function is called;
  • The second function is the error callback function. When an error is published, this function is called.

If we load the "rxjs-1-basic-example.html" into the browser, we can see that the time is displayed and continuously updated for every second in all the "divs". All the subscribers received the notification data for the current time published by the "ClockSubject.next(getTime())" through the "ClockSubject".

Opps - Error Is A Problem?

In order to keep the first example simple, we did not try the error notifications. But errors do occur and it is necessary to publish error notifications to the subscribers. Now let us take a look at the "rxjs-2-error-example.html".

JavaScript
let i = 0;
        
// Set a timer to update the subject
setInterval(function() {
    if (++i == 5) {
        i = 0;
        ClockSubject.error('An artificial error!');
        return;
    }
            
    ClockSubject.next(getTime());
            
}, 1000);

In order to test error notifications, I artificially broadcast an error notification for every five seconds.

JavaScript
ClockSubject.subscribe(
    function(time) {
        element.innerHTML = time;
    },
    function(error) {
        element.innerHTML = error;
    }
);

If a notification is received by the subscriber, the "div" will display the time. If an error is received, the "div" will display the error message.

If we load the "rxjs-2-error-example.html" into the browser, we can see that the time is displayed and updated. But when an error is received, the whole web page stops. Any further updates on the time no longer take effect.

Error Is A Problem

According to this link, error is a problem. Any "error()" call to a subject basically kills the subject. It is no longer alive, and it stops broadcasting any further notifications or errors. In this example, any "ClockSubject.next(getTime())" is not sent to the subscribers after the first call of the "ClockSubject.error('An artificial error!')".

A Wrapper of the RxJS Subject

In many cases, we do want a subject that keeps alive after broadcasting an error. To keep the subject alive, I created a simple wrapper subject in the "rxjs-3-error-handle-example.html".

JavaScript
// Wrapper of a Subject that does not stop on Error notification
Rx.FullSubject = function() {
    let self = this;
        
    let nSubject = new Rx.Subject();
    let eSubject = new Rx.Subject();
        
    self.subscribe = function(ns, es) {
        nSubject.subscribe(ns);
        eSubject.subscribe(es);
    };
        
    self.next = function(value) {
        nSubject.next(value);
    }
        
    self.error = function(error) {
        eSubject.next(error);
    }
}

The "FullSubject" has two RxJS subjects:

  • The "nSubject" is responsible for broadcasting notifications
  • The "eSubject" is responsible for broadcasting errors

Instead of using "error()" method to broadcast the errors, the "eSubject" uses the "next()" method. After sending an error, the "eSubject" is still alive, so the "FullSubject" is still alive.

JavaScript
let ClockSubject = new Rx.FullSubject();

If we load the "rxjs-3-error-handle-example.html" into the browser, we can see that when an error is sent, the error message is displayed in the "divs".

But when the time notification is sent, the current time is displayed in the "divs". The "FullSubject" remains alive after sending the error messages.

Points of Interest

  • This is a note on RxJS subjects;
  • An RxJS subject is a JavaScript object that broadcasts notifications to all the subscribers from any publishers;
  • The RxJS subjects may be useful to communicate among React or Angular components;
  • I hope you like my postings and I hope this note can help you one way or the other.

History

  • 7/3/2017: First revision

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
I have been working in the IT industry for some time. It is still exciting and I am still learning. I am a happy and honest person, and I want to be your friend.

Comments and Discussions

 
PraiseArticle Pin
Diyet31-Aug-17 13:24
professionalDiyet31-Aug-17 13:24 
AnswerHi Pin
Tony Herbaut16-Jul-17 8:36
Tony Herbaut16-Jul-17 8:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.