RxJS – Part 1 – Introduction

This entry is part 1 of 6 in the RxJS series

Introduction to RxJS

Reactive programming is nothing new in programming world. It has been used over 40 years ago or even before that. It started to bloom recently along with micro-services and functional programming. Idea is that we have something that represents a value over time which might constantly change. Most of the time when working with reactive programming we will be dealing with asynchronous programming. Even before Angular 2.0 was released Google or precisely Angular team decided to adopt and use RxJS internally in their framework. Since then it has grown rapidly in popularity.

And what is RxJS ? It is a JavaScript implementation of the ReactiveX library – a library for composing asynchronous and event-based programs by using observable sequences. ReactiveX itself is an abstraction of library that you can use on different platforms and with different languages. In addition to RxJS, ReactiveX has implementations in several other most popular languages. For the full list refer to the languages page on the official website.

RxJS is all about asynchronous programming with observable streams or sequences of events. Image something array-like that gets populated and changed over time. Opposite to array which has size limitation a stream can continue infinitely into future. With RxJS we can also work with events, promises, regular arrays or array like variables. More about that later on.
Now, what is so special about Rx and RxJS? RxJS lets us use asynchronous operations that usually return a single value in combination with streams (or events). And we know that streams and events in most of the cases produce values constantly. And they let us do that in a nice, fluid and composable way with tons of operators available out of the box. Ever used Underscore or Lodash? Or maybe you used LINQ in C#? Then you know how nice it is to use those tools with collections. Well, RxJS provides similar features for “asynchronous collections” and bunch of other things.
This all might be a bit confusing at the moment so lets move to next part and see how this thing actually works.

Pillars of RxJS

Three key players in RxJS are:
  • Producer
  • Observable
  • Observer
Producer is the source of values for the observable. It can be an array, iterator, web socket, events, etc.
Observable is basically a link between Producer and Observer. Observable will notice Observer whenever Producer has new values to send.
Observer is just an object with 3 methods on it:
  • next
  • error
  • complete
Using Observable Producer passes values to next() method on Observer object.
Most of the time we will use only two of those terms: Observable and Observer, just for the sake of simplicity. However, it is good to know that Observable is just a function that connects Observer and Producer. 

Subscribing to events

In JavaScript we are using publish – subscribe pattern when we are working with events. We can create our own events and emit values for specific use cases and we can subscribe to those events. We can also subscribe to DOM events. For an example we can subscribe to click event on one of the HTML elements.
let button = document.getElementById('btnClick');

button.addEventListener('click', onButtonClick);

function onButtonClick(event: MouseEvent) {
 console.log(event.target);
}

That means that we subscribe to ‘click’ event of btnClick DOM element and every time event is triggered function onButtonClick will be called.
In RxJS we have an Observer. Observer listens to, or subscribes to, an Observable.
In ReactiveX an observer subscribes to an Observable. Then that observer reacts to whatever item or sequence of items the Observable emits. This pattern facilitates concurrent operations because it does not need to block while waiting for the Observable to emit objects, but instead it creates a sentry in the form of an observer that stands ready to react appropriately at whatever future time the Observable does so.

 

Therefore we consider Observable to be a sort of publisher (creator, producer) and Observer is a subscriber (consumer).

Also, with RxJs we can represent multiple asynchronous data streams from different sources as one. We can subscribe to that event stream using the Observer object.

 

Subscribing to an Observable

Lets see how we subscribe to an Observable:

As we can see on Observer class we have 3 main methods: next, error, complete. Observable invokes Next() method on the Observer object whenever there is a change in the source (array, stream etc.).

Whenever there is a value to produce Observable triggers the next() method.

If something throws an exception and Observable runs into error it will call error() method on Observer.

Once an error happens Observable stops calling the next() method. Furthermore, complete() method will not execute after that.

It is possible that Observable has no more values to produce from data source. In that case Observable calls complete() method on Observer. In simple example above where we have array of strings as data source this will be the case.

In conclusion, error or complete function can say that there is no more data to send ot Observer. Only one of them may occur, never both!

If we look at dev console in Chrome we can see the following output:

We can also use functions to subscribe to an observable. It would make more sense in last example to use 3 functions instead of making new class and creating an object instance.

This is how we would do it with 3 simple functions:

 

And we would of course get the same output as before.

 

Real world use cases

This looks cool and nice but you are probably thinking why would you even consider learning more about RxJS? Why would you use it in your application?

Some of the obvious examples are pages that use WebSocket protocol. Sites that use chats, messaging, real time graphs and statuses. We probably do not want our users to spam the chat with their messages. On a page with real time statuses we do not want our users to refresh like a madman and send too many requests to our server. Therefore this would be an obvious good use case for RxJS, since it is designed for async data streams. Furthermore, RxJS has tons of operators that can handle async streams and manipulate them in a really nice and fluid way.

Another good use case is type-ahead search. Lets say we have simple notes application with thousands of users online! And users wants to find a specific note, maybe something they saved months ago. If user is typing fast and wants to search our database we certainly do not want to send a request as every user types. We want to handle the input from user and possibly send request only every 500 ms.

More about this in next few posts! If you wanna jump directly to the example of using RxJS in a chat application click here.

Summary

We saw that Observable delivers streams of data asynchronously and it can do so until it exhausts data source or it can continue infinitely in future.

Observable serves as wrapper of producer. On other side we have Observer. Observer is a consumer of the data that gets produced.

Observer has 3 main methods: next, error, complete. Whenever Producer has data to produce it uses next method and sends in value.

RxJS will come in really handy when we use apps that consume real-time data: chat applications, real time graphs, real time statuses. In these apps we probably want to have more control over users input and handling the stream of data to them. It also comes in handy when we want to limit the constant keyboard / mouse input from the user. One common example would be type-ahead search.

You can use RxJS anywhere where you have your JavaScript code. It will work both in browser and in Node.js applications.

That is all for now. In next post we will talk more about Observable and explore some other related concepts. After that we will talk about operators and real-life use cases of RxJS. We shall see some examples of RxJS in real action.

If you want to play around with RxJS you can find the sample code with webpack and TypeScript set up at my GitHub repository – rxjs-playground.



RxJS Series Navigation: Previous post:
Next post: RxJS – Part 2 – Observable >>



Ibrahim Šuta

Software Engineer, Mentor and Consultant interested and specialising in ASP.NET Core, C#, JavaScript, Angular, React.js. Experienced in MeteorJS, Node.js, ASP.NET, Windows Forms and Web Forms as well.