GID Master

Sign in

RxJs — Reactive and Imperative Programming

Angular uses RxJs as part of its ecosystem, honestly, it is the best library by far. RxJs definitely changed the way that front-end developers manipulate and transform data before displaying on screen.

Although RxJs it is not a new concept, most developers still struggle to understand the difference between reactive and imperative programming.

The concept of reactive programming using observables, pipes and operators makes our life a lot easier. Although you still find a bunch of developers coding in an imperative way, even with this out of Angular concept, unfortunately, it still happens.

RxJs is a huge library with a very steep learning curve, that’s why people are scared of it and try to avoid this natural and unavoidable transition.

RxJs Imperative Programming

It’s a common mistake subscribe an observable directly and reserve the result in an external variable. It goes against the entire concept of manipulating and transforming your data in order to get different results, it means that you’re pretty much using promises to get your data and that’s all.

The example below is not wrong at all, but it doesn’t follow the idea of reactive programming, it nests logic inside an observable instead of streaming the data.

Let’s see a common example of how you shouldn’t do.

// TYPESCRIPT

let tasksCompleted = [];
let tasksPending = [];
tasks$.subscribe(
data => {
tasksCompleted = data.filter(obj => obj.completed);
tasksPending = data.filter(obj => !obj.completed);
}
)

// YOUR TEMPLATE

<h1>Completed Tasks</h1>
<ul>
<li *ngFor="let task of tasksCompleted">{{ task.name }}<li>
</ul>

<h1>Pending Tasks</h1>
<ul>
<li *ngFor="let task of tasksPending">{{ task.name }}<li>
</ul>

Besides the fact that it can cause side effects to your data, even so you still have to unsubscribe all your listeners once Angular destroys the component.

You should avoid to subscribe your observable in the TypeScript file, unless you need to use the result in order to calculate something else. Even though you can use operators like tap to add this result into an external variable without subscribing it there.

RxJs Reactive Programming

Reactive programming is a better way to organise your observables, it outputs exactly the data that you are looking for. So you don’t need subscribe, create external variables or even face side effects to get your data.

We simply define stream of values using the observables and transform them using pipes.

Let’s see the best way to get the same result.

// TYPESCRIPT

let tasksCompleted$ = tasks$.pipe(
map(data => data.filter(obj => obj.completed))
);

let tasksPending$ = tasks$.pipe(
map(data => data.filter(obj => !obj.completed))
);

// YOUR TEMPLATE

<h1>Completed Tasks</h1>
<ul>
<li *ngFor="let task of tasksCompleted$ | async">{{ task.name }}<li>
</ul>

<h1>Pending Tasks</h1>
<ul>
<li *ngFor="let task of tasksPending$ | async">{{ task.name }}<li>

If you notice, we are using the same observable to filter the result creating a new observable, it makes your code a lot clear without subscribing and doing manipulations.

Angular handles everything if you use async pipe, the component subscribes and unsubscribes automatically. It’s is great, right ? You don’t need to worry about leak of memory leaving a lot of subscribed observables activated in your components.

Conclusion

This is a simple example that can help you to visualise the difference between imperative and reactive programming using RxJs, but it is more obvious in real life when a simple module loads tonnes of observables.

Web Architect — Full Stack Developer — Mobile Web Specialist