Leçon 08 · Phase 1 — Réactivité moderne RxJS · ~18 min

RxJS #1 : c'est quoi un Observable

Un signal répond à « quelle est la valeur maintenant ? ». Un Observable répond à une autre question : « préviens-moi à chaque fois qu'une nouvelle valeur arrive ». C'est un flux de valeurs dans le temps auquel on s'abonne. C'est la brique de RxJS, et le langage natif d'Angular pour tout ce qui est asynchrone (HTTP, événements, temps réel).

Pourquoi ça compte pour Alliance Leur ERP est plein de choses qui arrivent dans le temps : une mesure de capteur qui tombe chaque seconde, une réponse d'API GraphQL, la frappe de l'utilisateur dans un champ de recherche. Tout ça, côté Angular, ce sont des Observables. HttpClient renvoie un Observable, Apollo aussi. Tu ne peux pas brancher leur API ni reviewer un composant qui charge des données sans savoir lire un subscribe. C'est le socle de la phase 3 (GraphQL).

1. L'idée : un flux de valeurs dans le temps

On reprend notre fiche poste. Jusqu'ici elle affichait des notes. Maintenant on veut afficher la température live du poste : une nouvelle mesure arrive du capteur toutes les secondes. Ce n'est pas une valeur, c'est une suite de valeurs étalée dans le temps — exactement ce qu'un Observable modélise.

Un service nous expose ce flux. Le $ à la fin du nom est une convention RxJS qui signifie « ceci est un Observable » :

import { Observable } from 'rxjs';

export class PosteService {
  // flux des mesures d'un poste : émet un number toutes les secondes
  mesures$(id: string): Observable<number> {
    return new Observable(sub => {
      const t = setInterval(() => sub.next(lireCapteur(id)), 1000);
      return () => clearInterval(t); // nettoyage quand on se désabonne
    });
  }
}

Trois choses qu'un Observable peut t'envoyer : des valeurs (next, autant qu'il veut), une erreur (error, qui termine le flux), ou un signal de fin (complete). Un flux de mesures, lui, ne se termine jamais tout seul : il émet à l'infini jusqu'à ce que toi tu coupes.

Analogie : l'IEnumerable paresseux de LINQ En C#, var q = nombres.Where(n => n > 0).Select(n => n * n); ne calcule rien : tu as juste décrit un pipeline. Le travail démarre au foreach (ou .ToList()). Un Observable, c'est pareil : tu le déclares, tu le composes… et rien ne tourne tant que personne ne s'abonne. Côté .NET tu as même l'équivalent exact, IObservable<T> (Rx.NET) : RxJS en est le cousin JavaScript. La différence avec IEnumerable : ici c'est le flux qui te pousse les valeurs quand elles arrivent (push), au lieu que tu les tires une par une (pull).

2. subscribe() — rien ne se passe sans abonnement

Un Observable est paresseux et froid : tant que personne n'appelle subscribe(), le producteur (ici le setInterval) ne démarre même pas. S'abonner, c'est « ouvrir le robinet ». On branche le flux dans la fiche poste, et à chaque mesure reçue on met à jour un signal (qui, lui, alimente le template) :

import { Component, signal, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';

export class FichePosteComponent implements OnInit, OnDestroy {
  mesure = signal<number | null>(null);
  private sub?: Subscription;

  constructor(private postes: PosteService) {}

  ngOnInit() {
    // MAINTENANT le flux démarre. À chaque mesure → on écrit dans le signal
    this.sub = this.postes.mesures$('A12').subscribe(m => this.mesure.set(m));
  }

  ngOnDestroy() {
    this.sub?.unsubscribe(); // on coupe le robinet, sinon fuite mémoire
  }
}

Template : <p>Température : {{ mesure() ?? '—' }} °C</p>. Remarque le pont entre les deux mondes : l'Observable gère le « ça arrive dans le temps », le signal gère le « voici la valeur courante à afficher ». subscribe prend aussi un objet à trois callbacks si tu veux gérer erreur et fin : .subscribe({ next, error, complete }).

3. Observable vs Promise

Tu connais les Promise (leçon 03). Pourquoi Angular préfère les Observables pour les données ?

PromiseObservable
Nombre de valeursune seulezéro, une, ou une infinité
Démarrageimmédiat (eager)au subscribe (lazy)
Annulable ?nonoui (unsubscribe)
Composable ?peuoui (opérateurs — leçon 09)

Pour un appel HTTP qui renvoie une fois, les deux marchent. Mais dès qu'il faut annuler, réémettre ou transformer le flux (une recherche qui se relance à chaque frappe, par ex.), l'Observable gagne. D'où son omniprésence dans Angular.

Observable vs signal — ne les oppose pas, ils coopèrent Un signal est une valeur que tu lis quand tu veux (mesure()) : il a toujours une valeur courante. Un Observable est un flux qui te pousse des valeurs quand elles arrivent : pas de « valeur courante » en soi, juste des événements. Règle pratique : RxJS pour orchestrer l'asynchrone (HTTP, debounce, annulation), signals pour l'état affiché. Le pont des deux mondes (toSignal) arrive en leçon 10.
Œil de tech lead (1) Le piège n°1 de revue RxJS : un subscribe sans désabonnement sur un flux qui ne se termine pas (mesures, événements, websocket) = fuite mémoire. L'abonnement survit au composant détruit et continue de tourner. Toujours unsubscribe (ou mieux : async pipe / takeUntilDestroyed, qu'on verra). (2) Oui, ce subscribe + unsubscribe manuel est verbeux — c'est volontairement la version « à la main » pour comprendre. Les opérateurs (leçon 09) et l'async pipe (leçon 10) font fondre ce code. (3) Ne subscribe jamais dans un autre subscribe (callback hell) : ça se compose avec des opérateurs.

4. Vérifie ta compréhension

Quand un Observable commence-t-il réellement à produire ses valeurs ?
Quelle est la différence clé entre un Observable et une Promise ?
Que risque-t-on en oubliant unsubscribe sur un flux infini ?
À retenir Un Observable est un flux de valeurs dans le temps : il peut émettre next (n valeurs), error (fin en erreur) ou complete (fin propre). Il est paresseux et froid : rien ne tourne avant subscribe() (comme un IEnumerable LINQ avant le foreach). Vs Promise : plusieurs valeurs, annulable, composable. Vs signal : l'Observable pousse l'asynchrone, le signal tient l'état affiché — ils coopèrent. Réflexe de lead : tout subscribe manuel sur flux non terminé doit être unsubscribe, sinon fuite mémoire.
Source primaire à lire (10 min)

RxJS — Observable (officiel) pour la mécanique next/error/complete, puis Angular — Making HTTP requests pour voir un Observable réel renvoyé par HttpClient. On enchaîne sur les opérateurs en leçon 09.

Je suis ton prof — pose-moi des questions. Tu veux qu'on fasse tourner la fiche poste avec la température live (un vrai setInterval + abonnement), ou que je te montre côte à côte le même chargement de données en Promise vs Observable pour sentir la différence ? Demande-moi, ici, maintenant.
◀ 07 · Signals #2 : effect(), input() & output() Suivant : 09 · RxJS #2 : opérateurs (map, filter, switchMap) ▶