While writing web applications using Angular framework, it is almost always necessary to use observable objects. While using HttpClient service or creating own asynchronous event emitters for cross-component communication (often in a parent-child relation), we are dealing with observables. Let’s take a closer look at the tool that has revolutionized the way data flow is handled in an application.
What is an object of type observable?
Let’s start with a real-life example. Surely, while browsing various websites, everyone came across some banners offering the possibility of subscription to, for example, a newsletter of an internet portal. After such an action, notifications / news / posts will be sent to our e-mail box at the time of their publication. Such data will then be provided to us until our subscription is cancelled.
The presented situation is nothing else than analogue of the main functionality of the observable, where the e-mail notifications correspond to data streams to which it is possible to “connect”, listen to “flowing” values and “disconnect” at any moment. Moreover, many application elements can be subscribers to one stream at the same time.
What does RxJS offer?
The greatest strength of the library is to simplify the use of asynchronicity and the creation of event-based applications thanks to observable sequences. Observables can be created from scratch using, for example, the of, generate or create operators, or emitted by timers and intervals. The library documentation is rich in examples and explaining the way the mechanisms work. It is a great help in understanding the functions of the library (for more information see learnrxjs.io/rxjs-primer).
The observable object was already discussed, as well as the main feature of the RxJS library, but the most important case should also be mentioned – the offered functions. RxJS already enables many operations related to the mentioned data streams, such as data filtering, data transformation, error handling , stream creation and combination.
An example of the stream combination is the merge operator, shown in the example below, where the colorful bubbles on the axis are a simplified graphical representation of a data stream. In general, combination operators are responsible for joining data of multiple observables in different variations, like concatenation, fetching of the first emitted value of multiple observables, waiting with the subscription for all observables to be completed and so on.
Stream data can be filtered by using custom conditions (filter, find, first), time related functions (audit, auditTime, debounce, debounceTime) or taking distinct values based on the previous emitted one (distinct, distinctUntilChanged, distinctUntilKeyChanged).
We’ve got also plenty of operators responsible for data transformation, which provides such functionality like object/value mapping, grouping, buffering, conditional splitting, windowing and accumulation.
In order to understand the next chapter, I will give a brief explanation of the definition of a promise object. Promise is actually a poorer version of the observable, it only supports single events, is not cancellable, and has a much smaller operator base compared to observables. Using promises is more inconvenient and not recommended anymore.
What changes will the latest seventh version of RxJS introduce?
One of the most attractive features of integrating RxJS into your code is the fact, that the more you use it, the more you can do with it. So let’s discover the functions that will make the developers work even easier in the near future. The full release notes can be found here (this article contains only information about the first beta version of the seventh RxJS version).
- lastValueFrom and firstValueFrom
The firstValueFrom operator converts an observable to a promise that is being resolved when the first value in the data stream appears. When the value arrives, the subscription is automatically cancelled. When the stream ends without any value being emitted, an error is returned.
The lastValueFrom method works in a very similar way, except that it waits for the stream to end, and then returns the last emitted value. Both methods will be particularly useful in cases where we are dealing with streams that constantly emit many values and do not close immediately.
An example of the use of the lastValueFrom operator is presented below, but firstValueFrom is used analogously. The getUsers() method queries an external API that returns an observable object.
- retry operator configuration
Retry nowadays is used to repeat the events sequence of the stream if the observable issues an error. For now, just the value corresponding to the number of repetitions was passed to the function. In the new version, the retry operator will be expanded with an interface containing an optional resetOnSuccess field (false by default), which will cause the counter to reset during each successful event emission.
In the example above, the query will be repeated twice on failure, and the repeat counter will reset on success.
- selector in fromFetch operator
The fromFetch operator allows you to make an http query , which will then return an so-called Chunked Response, which means that the received data is sent fragmentarily. Passing a selector to the fromFetch operator allows us to define the information we want to extract.
Here are some example of how to use this feature.
- type guards support for groupBy
The groupBy operator will in the future allow us to group items not only based on the selected field, but also based on the type, by passing a type guard in place of the selector. A Type guard is nothing more than a function that determines the type of a given variable.
A short example:
The functionalities presented above are certainly the most important, but not the only changes that the future version of RxJS will bring. In addition to the examples just mentioned, many bugs have been fixed, memory usage has been improved, and minor modifications to the combineLatest operator and the TimeoutConfig interface have been introduced.
Summing up – the RxJS library with each new version becomes a more and more powerful tool, and it will not be different in the case of the seventh version. We will certainly see even more useful functionalities in the future to facilitate asynchronous data handling in Angular framework.