RxJS Declarative Pattern in Angular
This is a short summary on how to use a declarative pattern in Angular with RxJS.
If you are interested in the whole post, read RxJS Declarative Pattern in Angular on Medium.
To get the best out of this post, you should be familiar with Angular, RxJS, and observables.
RxJS doesn’t make your code declarative
Using RxJS doesn’t make your code declarative. Actually, as soon as you use the subscribe()
method, you are going imperative!
For this reason, we need to be declarative on purpose.
Step 1: Create the service
Let's start by creating a service where we declare a variable todo$
.
The dollar sign is a convention that indicates that the variable is an Observable and not the actual data.
The data coming from the url will be
- passed through a pipe
- passed through the RxJS tap operator
- saved in
todo$
However, if you just try this, nothing will happen!
You won't see anything in the console.
Step 2: Assign the observable to a local variable
Let’s move to the component.
The key line here is line 10, which is:
data$ = this.todoService.todo$;
We defined a local variable called data$
. We assign the observable from the service to the variable to make it available in the component.
Note that we are not telling Angular to subscribe or unsubscribe! We are not even seeing an observer! This is where the real declarative style shines.
In the end, we just want to display some data in the template. That is our goal. How Angular achieves it is not our business.
Once again, if you just try this, nothing will happen!
You won't see anything in the console on in the template.
This makes sense because we didn't tell Angular what our goal is!
Step 3: Use the local variable with async pipe
Let’s move to the template.
Here we tell Angular what needs to be done: Show the title of the object in the template when data is available.
To do that, we use the async pipe.
The async pipe automatically subscribes and unsubscribes, which is shown below:
// app.component.html
<div *ngIf="data$ | async as data">
{{ data.title }}
</div>
- First, we bind to
data$
from the component. - Second, we use the async pipe to automatically subscribe and unsubscribe to
data$
- Third, we use
as data
to define the variable that will host the value from the observable. - Finally, we can use data across the template as we did before.
A more comprehensive example and a comparison between this approach and the classic imperative approache is available on RxJS Declarative Pattern in Angular on Medium.
Let me hear your opinion!