DEV Community

loading...

An Introduction to RxJs Observables

Vince
Full stack web developer, lover of Open Source, hacker of things.
・3 min read

Understanding RxJs

Reactive Programming can be extremely difficult to understand. Here is a quick introduction to RxJs to hopefully get you started using reactive programming.

What Is An Observable?

An Observable is, in the simplest form, the result of an asynchronous operation. We can use them in place of Promises for a lot of asynchronous tasks. However an Observable allows for us to do complex logic on an async data stream with only a few lines of code.

The Basics

Before we get to the complex work we can do with Observables we should first understand the basics. There are a lot of helper methods to create Observables, for this example we will make use of interval(period: number). It creates an Observable that returns an incremented number every period milliseconds. Creating this observable is as simple as:

interval(1000);
Enter fullscreen mode Exit fullscreen mode

This Observable will "emit", the term used for when an Observable produces a new value, the following 1 (one second) 2 (one second) 3....

Subscriptions

In order to get the emitted values from the above Observable we will need to "subscribe" to it.

const source = interval(1000);
source.subscribe(value => {
  console.log(value);
});
Enter fullscreen mode Exit fullscreen mode

The above code will print out the emitted values as they are emitted from the Observable.

The Idea of the River

I find that when working with Observables it often helps to think of the "source" Observable as a river, with each emission being a boat that is floating down the river. By Subscribing to an Observable we are being given access to see the boats that are on the river. Next we will learn how to manipulate how and when those boats are perceived by someone watching the river.

The Pipe Operator

Here we are going to get into the more complex things we can do with Observables. We can achieve this using the pipe() function that exists on an Observable. Taking the source from above we can create a piped observable that only passes along even numbers.

const source = interval(1000);
source.pipe(
  filter(value => value % 2 === 0)
)
.subscribe(value => console.log(value))
Enter fullscreen mode Exit fullscreen mode

This will print out 2 ... 4 ... 6 ... etc. We can see that the Observable has operators that can act upon the emitted values. Here we use filter(select: Function) to only accept values that are even. This is similar to the filter() function on arrays in JavaScript.

There are a load of pipeable operators that we can make use of.
Assume we have an Observable who's source is click events:

const source = fromEvent(document, 'click');
Enter fullscreen mode Exit fullscreen mode

This will create an Observable who will emit every time there is a click event on the page.

Now say we need collect these click events into batches of 5 and then send them off to an arbitrary API for processing, which will then return a value from that processing which we need to print out, we will assume we have a service written that is ready to make the API call since that is out of the scope of this article. Here we can make use of the bufferCount(bufferSize: number, startBufferEvery: number = null) to do this.

const source = fromEvent(document, 'click');
source.pipe(bufferCount(5))
Enter fullscreen mode Exit fullscreen mode

bufferCount(5) will collect 5 emissions from source and then emit them as an array. Now that we have our events batched we need to send them off to the API. Our service will return an Observable from its service call, so we need to take the value from our source and pass it to a function that makes a new Observable, and then return the new Observable. We can make use of the mergeMap() operator.

const source = fromEvent(document, 'click');
source.pipe(
  bufferCount(5),
  mergeMap(events => this.myAPIService.serviceCall(events))
)
.subscribe(processedEvents => console.log(processedEvents));
Enter fullscreen mode Exit fullscreen mode

In a few lines of RxJs operators and functions we have created some, albeit odd, logic that could take many more lines to complete with Promises.

Conclusion

RxJs is an extremely powerful tool that can be extremely difficult to grasp, especially when working with large applications that retrieve data from multiple locations. I hope this article has helped shed some light on how Observables work. Feel free to drop any comments, questions, or concerns in the comments below.

Additional Resources

When I am working with Observables I often check learnrxjs.io. They have a list of Operators with examples and explanations of the operator. There is also a list of recipes showing the operators in action.

The official docs also contain useful information including marbles diagrams, which we will cover in the next article, and examples.

Discussion (0)

Forem Open with the Forem app