RxJS & Angular Signals
Different strategies for using Observable and Signal together

v.7

v.18

Fabio Biondi
Google Developer Expert
Microsoft MVP
# Subscribing to an Observable in Angular
We have already seen in the previous lessons how to listen for the values emitted by an observable using the subscribe
method:
# Using the async
Pipe
We have also explored how the async
pipe serves as an efficient strategy in Angular for subscribing to an Observable directly within the template.
It helps saving lines of code while eliminating the need to manually handle unsubscription, as this is automatically managed by the pipe.
The example below shows a timer in the HTML template that updates a counter every second:
# Observable and Signal
We can also combine signals and observables to take advantage of the latest Angular API.
In this snippet we subscribe the timer$
observable and update the timer
signal value accordingly (so they are in sync and contain exactly the same values):
For example when you have an Observable that emits data but you want to use the signal functionalities to calculate derived states, with computed
, or to make side effects at every change of the signal value, with effect
.
Using signals will be also useful in the next generation zoneless Angular applications
In the next example:
- We now display the
double
signal value in the template which represent the value of the timer
signal multiplied by 2
- The
effect
function is automatically invoked each time the timer
signal updates. Here you might perform some effects like saving the value on local storage, change routes, make HTTP calls and so on...
Of course this is a trivial example but in reality you might have an Observable generated by Angular that you want to treat as Signal. For example router events, valueChanges
of a reactive form and so on.
# toSignal
The syntax of the previous code snippet didn’t seem a little too "verbose"?
Yes, it is!
Instead of manually subscribing the signal we can do it automatically with the toSignal
function.
This function transforms an Observable into a Signal: it accepts an Observable as parameter, subscribes to it and automatically converts the values emitted by the Observable into a Signal update.
It also unsubscribes the Observable when the component is destroyed, just like the async
pipe.
toSignal
and Pipeable Operators
In the following snippet, we will update the implementation to:
1Create the timer
signal from an interval
creation operator, just like in the previous example
2Filters data by only emitting even values
3Transform the value by multiplying it by 2
Not suitable for beginners
Next examples are a bit difficult to understand if you just started using RxJS or Angular, since we use concepts we haven’t yet faced in this book.
So don’t worry if something is not really clear. We will address this topics later in the book.
However, for those who already have some experience, I am sure they will understand the potential.
# toSignal and Http calls
Let’s see a couple of examples that are a bit more realistic and combine features from Angular and RxJS.
In my opinion, even if they are simple examples, they are very cool because you should start to understand the benefits and the potential of a conscious use of RxJS.
toSignal, HttpClient
& concatMap
In the next example:
- We will create a
counter
that emit values from 1
to N
every second. Each number represents the todo identifier (id
) that we will use to make an HTTP call and retrieve a specific todo entity.
- When
counter
changes we load a new Todo from a REST API, /todo/[id]
, using the counter value as the id
of the todo
.
So, as you can see from the screenshot below, we have an HTTP request every second with a different id
:
- As result, we display the
title
of the current Todo in the HTML template and it's updated every second:
Run the example below to see it in action:
In this example, with a few lines of declarative code:
- We created a
counter
from 0
to N
, emitted every second using the RxJS interval
creation operator.
- We used
map
pipeable operator to add 1
to each emitted value and avoid the counter
having a value of 0
. So it emits values from 1
to N
. Why? Because we don't have a todo with 0
as id
.
- Each time the
counter
changes, we invoked the /todo/[ID]
API using the counter
as the todo id
:
So we retrieve a new todo
entity from the REST API call every second and we consequently update the todo
signal value, thanks to the toSignal
function.
The signal is then updated every time the observable emits a new Todo item and we display its title
in the HTML template.
As you can see, it takes longer to explain than to write :)
You may not yet be familiar with the concatMap
operator, which we will discuss later in this book.
For now, it is enough to understand that it is an operator that subscribes to the Observable returned in its function and emits its result.
toSignal with Reactive Forms
Fundamentals are important!
I want to point out that this example is very similar to the previous one. There are no new concepts but the result is completely different.
It demonstrates how concepts learned can be exploited in multiple scenarios and use cases
In the following example:
1We will listen for changes to a form input
2We will wait for the user to finish typing (a technique known as “**debounce**”
3We will call an API to search for the entered word in a list of users..
Here is the final result:
API
Here is the endpoint we're using in these snippets: