Lorsque la core team de Angular a annoncé l'arrivée du concept de Signals
, plusieurs interrogations se sont soulevées quant à l'utilisation de la bibliothèque RxJS
qui a été jusque-là un atout très important pour le framework Angular.
Est-ce que
Angular Signals
remplaceraRxJS
?
Est-ce queAngular Signals
etRxJS
sont complémentaires ?
Quel sera l'avenir deRxJS
dans Angular ?
Cet article vise à mettre la lumière sur ces interrogations ainsi que sur l'utilisation du package RxJS Interop
que la core team de Angular a mis à disposition des développeurs.
Est-ce que
Angular Signals
remplaceraRxJS
?
Angular Signals
n'a pas pour but de remplacer RxJS
. Le concept de Signals
a été introduit afin d'optimiser le système de détection des changements dans nos composants Angular lorsque nous mettons à jour une variable ou un objet. Ce système a été conçu autour la bibliothèque Zone.js
qui a démontré ces limites que j'ai eues à évoquer précédemment dans cet article Les nouveautés en Angular 16 (Partie 1)
Nous comprenons donc que Zone.js
n'a rien avoir techniquement avec RxJS
. Ce sont deux bibliothèques bien distinctes qui ont des buts différents.
Est-ce que
Angular Signals
etRxJS
sont complémentaires ?
Maintenant que nous savons que Angular Signals
n'est pas là pour remplacer RxJS
, nous aborderons leur complémentarité.
Après avoir suivi plusieurs discussions entre les membres de la core team et ceux de la communauté Angular, je peux affirmer que oui 😃
En effet, les Signals
permettent une gestion d'état synchrone tandis que la bibliothèque RxJS
le fait de manière asynchrone. La décision de choisir entre l'utilisation de RxJS
ou celle de Signals
dépendra donc de la complexité de nos opérations asynchrones et de l'environnement de développement existant. Pour des scénarios asynchrones complexes et des architectures basées sur des événements, RxJS
offre des outils puissants. En revanche, pour des cas simples d'événements typiquement synchrone ou lorsqu'une meilleure intégration avec les fonctionnalités spécifiques d'Angular est souhaitée, les Signals
peuvent être plus appropriés.
Quel sera l'avenir de
RxJS
dans Angular ?
Après être penché sur les deux premières interrogations qui constituaient des points d'ombre, il est légitime de se demander ce que nous réserve la core team Angular par rapport à l'utilisation de RxJS
dans le futur.
L'objectif de la core team de Angular est de rendre optionnel l'installation de bibliothèque RxJS
dans un projet Angular c'est-à-dire qu'à la création d'un projet Angular, la bibliothèque RxJS
ne sera plus une dépendance installée par défaut. Toutefois, la core team est bien consciente de la puissance des fonctionnalités de RxJS
. Pour faciliter la transition, ils ont mis en place le package RxJS Interop
.
RxJS Interop
d'Angular fournit des utilitaires utiles pour intégrer Angular Signals
avec les observables RxJS
. Voici quelques utilitaires ou helpers (en anglais) que nous offre cette nouvelle bibliothèque :
toSignal
La fonction toSignal
permet de créer un signal qui écoute en permanence la valeur d'un Observable
. Son comportement est similaire à celui du pipe async
que nous utilisons dans nos templates HTML, mais il est plus flexible et peut être utilisé n'importe où dans une application. Voyons ensemble ce cas d'utilisation :
import { Component } from '@angular/core';
import { AsyncPipe } from '@angular/common';
import { interval } from 'rxjs';
@Component({
template: `{{ counter() }}`,
})
export class Ticker {
counterObservable = interval(1000);
// Get a `Signal` representing the `counterObservable`'s value.
counter = toSignal(this.counterObservable, {initialValue: 0});
}
Comme le pipe async
, toSignal
s'abonne immédiatement à l'Observable
, ce qui peut entraîner des effets de bord. La souscription créée par toSignal
se désabonne automatiquement de l'Observable
donné lorsque le composant ou le service qui appelle toSignal
est détruit. Ainsi, nous pouvons transformer un comportement asynchrone en synchrone en utilisant pleinement le potentiel des Signals.
Cependant,
toSignal
crée une souscription. Il faut donc éviter de l'appeler plusieurs fois pour le mêmeObservable
, et réutiliser le signal qu'il renvoie.
toObservable
A l'opposé de l'utilitaire toSignal
, utilisez toObservable
pour créer un Observable
qui écoute en permanence la valeur d'un signal. La valeur du signal est surveillée par un effect
qui transmet la valeur à l'Observable
lorsqu'elle change. Voici un cas d'utilisation :
import { Component, signal } from '@angular/core';
@Component(...)
export class SearchResults {
query: Signal<string> = inject(QueryService).query;
query$ = toObservable(this.query);
results$ = this.query$.pipe(
switchMap(query => this.http.get('/search?q=' + query ))
);
}
Lorsque le signal query
change, l'observable query$
émet la dernière requête et déclenche une nouvelle demande HTTP. Dans l'exemple, on remarque l'utilisation deswitchMap
qui est un opérateurRxJS
ce qui est normal car comme nous l'avons précédemment annoncé, pour les tâches asynchronous,RxJS
demeure très efficace.
Il est à noter qu'il reste deux autres utilitaires à savoir outputFromObservable
et outputToObservable
que nous verrons plus tard dans un nouvel article.
En somme, comme nous l'avons remarqué, pour comprendre l'utilité de RxJS Interop
, il faut d'abord comprendre ce à quoi est destiné d'une part Angular Signals
et d'autre part RxJS
. Aujourd'hui, au travers de cet article, nous avons les idées claires de ce qu'il en sera du future de RxJS
avec l'arrivée de Angular Signals
.
Pour plus d'informations 👉 RxJS Interop