Reactive Programming in Javascript using RxJS

László Harri Németh
The Coding Hype
Published in
10 min readDec 11, 2018
Photo by Sora Sagano on Unsplash

Nowadays there is a hype around reactive programming. This article explains the motivation behind learning reactive programming, and the basic concepts to get started.

In this article I use Node.js as a runtime environment for learning RxJS.

Keywords: Node.js, NPM, Javascript, RxJS, Linux, Ubuntu, NVM, ReactiveX, Reactive Programming, Stream, Observable, Observer, Subscription, Operator, Subject, filter, map, pipe, scan, reduce, throttleTime, unsubscribe

DISCLAIMER: THE VIEWS AND OPINIONS EXPRESSED IN THIS ARTICLE ARE THOSE OF THE AUTHOR AND DO NOT REFLECT THE OFFICIAL POLICY OR POSITION OF THE EMPLOYER OF THE AUTHOR. THE ARTICLE IS NOT ENDORSED BY, DIRECTLY AFFILIATED WITH, MAINTAINED, AUTHORIZED, OR SPONSORED BY ANY CORPORATION OR ORGANIZATION. THE INFORMATION CONTAINED ON THIS ARTICLE IS INTENDED SOLELY TO PROVIDE GENERAL GUIDANCE ON MATTERS OF INTEREST FOR THE PERSONAL USE OF THE READER, WHO ACCEPTS FULL RESPONSIBILITY FOR ITS USE. ALTHOUGH THE AUTHOR HAS MADE EVERY EFFORT TO ENSURE THAT THE INFORMATION IN THIS ARTICLE WAS CORRECT AT THE TIME OF THE WRITING, THE AUTHOR DOES NOT ASSUME AND HEREBY DISCLAIM ANY LIABILITY TO ANY PARTY FOR ANY LOSS, DAMAGE, OR DISRUPTION CAUSED BY ERRORS OR OMISSIONS, WHETHER SUCH ERRORS OR OMISSIONS RESULT FROM NEGLIGENCE, ACCIDENT, OR ANY OTHER CAUSE.

Table of Content

The article is divided into the following sections:

  • Motivation and basics
  • Required knowledge
  • What is RxJS?
  • Fundamental concepts in RxJS
  • Preparation of runtime environment
  • Observable, Observer and Subscribe
  • Further Observable Creation Possibilities
  • Operators: Filter and Map
  • About the pipe
  • Further operators: scan and reduce
  • About throttleTime
  • Unsubscription with unsubscribe
  • Closer to the web
  • Conclusion
  • Resources

Motivation and basics

Todays highly interactive web applications and mobile apps the handling of user interface interactions is crucial. We can imagine the UI interactions as a series of events, or in other words, a stream of events. We can think of an event as a piece of information (data), which is available at a certain point in time. For example, a mouse click event happens when the user clicks with the mouse, and the data which is related to this event are the coordinates of the mouse pointer, when the click happens.

There are some fundamental concepts related to reactive programming, which are described in the following chapter.

For this tutorial I use RxJS, which is a Javascript library for reactive programming. Therefore the concepts described in this tutorial are the ones used by RxJS.

Required knowledge

In order to understand this article you need to have at least basic knowledge of the following:

  • Javascript
  • Node.js
  • Node Package Manager (npm)

What is RxJS?

RxJS is a Javascript library licensed under Apache-2.0 License. It is part of ReactiveX, which is a collection of open source projects. On the website of RxJS we can read the following definition.

RxJS is a library for reactive programming using Observables, to make it easier to compose asynchronous or callback-based code. This project is a rewrite of Reactive-Extensions/RxJS with better performance, better modularity, better debuggable call stacks, while staying mostly backwards compatible, with some breaking changes that reduce the API surface. — RxJS (https://rxjs-dev.firebaseapp.com/)

RxJS stands for Reactive Extensions for Javascript.

Fundamental concepts in RxJS

“blue ballpoint pen on white notebook” by Med Badr Chemmaoui on Unsplash

The following concepts are very important to understand if we would like to learn RxJS:

  • Stream: A stream is a sequence of data elements made available over time. A stream can be thought of as items on a conveyor belt being processed one at a time rather than in large batches. (Wikipedia)
  • Observable: RxJS represents asynchronous data streams using observable sequences. These observable sequences are called Observables. Observables can be used using push or pull patterns. (Source)
  • Observer: According to the definition, Observer is an interface for a consumer of push-based notifications delivered by an Observable. An Observer is a consumer of values delivered by an Observable. Observers are objects with three callbacks, one for each type of notification that an Observable may deliver: next, error, and complete. (Source).
  • Subscription: Subscribe is an operator. The Subscribe operator is the glue that connects an Observer to an Observable. In order for an Observer to see the items being emitted by an Observable, or to receive error or completed notifications from the Observable, it must first subscribe to that Observable with this operator.
  • Operator: Operators are 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 (Source). Subscribe is an operator.
  • Subject: An RxJS Subject is a special type of Observable that allows values to be multicasted to many Observers. While plain Observables are unicast (each subscribed Observer owns an independent execution of the Observable), Subjects are multicast. A Subject is like an Observable, but can multicast to many Observers. (Source)

Preparation of runtime environment

“grayscale photography of piled racks” by Ricardo Gomez Angel on Unsplash

As the runtime environment for the examples I use Ubuntu 14.04.5 LTS (trusty). I used Node.js version v6.11.2. My NPM version is 3.10.10. I assume that Node.js and npm is already installed in your system, and a new folder was created for these rxjs examples. In my system I named this folder workspace.

(In my system, Node Version Manager (nvm) is also installed (version 0.31.0). NVM is a powerful tool to manage multiple Node.js versions in your development environment. for further info about NVM you can check for example https://nodesource.com/blog/installing-node-js-tutorial-using-nvm-on-mac-os-x-and-ubuntu/)

The following steps are required to initialize our runtime environment:

  1. initalize the folder by generating a new package.json file (The reason behind creating this file can be read at https://docs.npmjs.com/creating-a-package-json-file):
npm init -y

After this we see the following:

2. install RxJS and other dependencies with the following command:

npm install rxjs

After this step our folder looks like the following:

The folder node_modules contains the installed Node.js modules.

3. Test if RxJS is really working. This is done by our first simple Javascript which looks like the following:

You can copy-paste this code to your own file, by starting the nano editor from the console:

nano rxjs-helloworld.js

In nano, you can save the file by pressing CTRL+O and ENTER. You can exit from nano by pressing CTRL+X.

To run the script you can use the following command:

node rxjs-helloworld.js

Or, if you don’t have the current directory in your path, you need to use

node ./rxjs-helloworld.js

The output looks like the following:

With this we have prepared our environment for trying out RxJS. The Hello World example will be explained later in this article. Remember that you can always run your code with

node my_script.js

Observable, Observer and Subscribe

Let’s look at the first example we have already seen.

In this example

  1. We define an observable with Observable.create(). In the input of this function call we specify a callback function, which receives observer as the parameter, and calls functions on this. The next function is called 3 times, and the complete function once.
  2. Then we call subscribemethod of the observable.

The Observer has 3 methods:

  • next: The callback to receive notifications of type next from the Observable, with a value.
  • error: The callback to receive notifications of type error from the Observable, with an attached Error. (More info about the error object here)
  • complete: The callback to receive a valueless notification of type complete from the Observable.

In the subscribe method of the observable we specify 3 callback functions as parameters. The first one is called when the next data is emitted by the observable, the second one is called when an error occurs, the third one is called when the observer completes its job, and there was no error.

The subscribe can be called also in different way, by specifying an object with 3 properties, like the following:

Further Observable Creation Possibilities

Observables can be created from different objects.

In the following example, observable is created out of an array of numbers.

Here, in case of specifying this callback function in the subscribe, we could also say:

observableFromArray.subscribe({
next: function(value) { console.log(value); }
});

It’s also fine that we don’t specify the error and the complete attributes.

We can convert strings as well.

We can create observable from events as well. For this, in Node environment, we need an event emitter. (Node.js contains event emitters by default, you can read more about this here.)

Operators: filter and map

Observables can be transformed to other Observables. This can be done by using operators. Examples of operators:

  • from
  • fromEvent
  • filter
  • map

There are plenty of operators, the list can be found here.

In the following example, filter call filters out the even numbers from the stream, and returns a stream which contains only the odd numbers x % 2 will be 0 in case of even numbers, and 1 in case of odd numbers. 1 is truthy, therefore the odd numbers will remain in the stream. After this we subscribe to the stream to print it out to the console.

We enhance this example by a map function, which doubles the emitted numbers:

The output of this second example will be:

Next: 2
Next: 6
Next: 10
Next: 14
Next: 18

About the pipe

In the above examples we used pipe(). In RxJS operators are pure functions. This means that they can be chained, and this chaining is done by using pipe() function on the observable. More info about piping can be found here.

Further operators: scan and reduce

The signature of scan operator looks like the following:

scan(accumulator: function, seed: any): Observable

Scan will call the accumulator function on the values over time, starting with value of seed as a basis.

In this example we calculate the factorial of numbers from 1 to 10.

The output is:

1
2
6
24
120
720
5040
40320
362880
3628800

Reduce is something similar, but it reduces the values to a single value in each call.

The output is: 3628800

About throttleTime

The definition of throttleTime() is quite simple: Emit latest value when specified duration has passed (source). What does this mean?

The result of the above code will be the following:

0
2
4
6
8
10
12
14
16
18
20
22
24
<...and the sequence goes on>

The interval(500) method emits a value every 500 milliseconds. The throttleTime(1000) method gets the latest value from the sequence every 1000 milliseconds (=1 second).

Unsubscription with unsubscribe

Let’s enhance the above example with an unsubscribe() call:

This will result in:

0
2
4
6
8
10
12
14
16
18

After 10 seconds the sequence stops.

Closer to the web

The last example below uses an HTML page with Javascript to try RxJS. The page shows a button, and when you click the button, it will show the current time. For this example I used another JS library: moment.js, for converting the time to the format I would like to see.

I also put this on Codepen so that you can try it.

Conclusion

This was a quick overview of RxJS, which definitely worth to dig deeper in it. It absolutely makes sense these days to learn it.

I hope you learned something new today. If you have any questions please leave a comment.

Resources

There are plenty of resources on the web regarding reactive programming. For this tutorial I used the following:

--

--

László Harri Németh
The Coding Hype

Software developer. Python, SQL, ABAP, Swift, Javascript, Java, C, C++, Ruby, noSQL, Bash, Linux. http://nlharri.hu http://github.nlharri.hu hello@nlharri.hu