Angular takeUntilDestroyed : éviter les fuites mémoires
Introduit en Angular 16, l'opérateur takeUntilDestroyed est un moyen plus intégré pour gérer les abonnements aux observables et éviter les fuites mémoires. Cependant, une attention particulière doit être portée à l'ordre des opérateurs dans les pipe pour que takeUntilDestroyed fonctionne correctement.
Fonctionnement
Soit l'exemple suivant avec un composant QuoteComponent:
Dans cet exemple, takeUntilDestroyed est utilisé pour se désabonner de l'observable userSelectedTag$ lorsque le composant est détruit. L'opérateur takeUntilDestroyed prend un paramètre de type DestroyRef qui permet de déclencher le désabonnement. Ce paramètre est facultatif dans les cas où l'abonnement se fait dans des contextes dits "d'injection". C'est le cas par exemple dans le constructeur ou dans les champs d'un composant (constructeurs indirects).
Ordre des opérateurs dans les pipe
Prenons l'exemple suivant :
Ici, nous utilisons switchMap pour déclencher une nouvelle requête à chaque fois qu'un tag est sélectionné. En utilisant takeUntilDestroyed dans le pipe, nous nous assurons du désabonnement de l'observable userSelectedTag$ lorsque le composant est détruit. Malheureusement, nous allons voir sur l'image ci-dessous que cela fonctionne partiellement.

Comme on peut le voir, lorsque le composant est détruit, on se désabonne bien de l'observable userSelectedTag$, mais l'observable quoteService.startUpdatingQuotes(tag) continue de tourner. Cela est dû à l'ordre des opérateurs dans le pipe. En effet, takeUntilDestroyed se désabonne de l'observable userSelectedTag$ mais pas de l'observable créé par switchMap.
Pour résoudre ce problème, il suffit de déplacer takeUntilDestroyed après switchMap dans le pipe:
Maintenant, lorsque le composant est détruit, l'observable créé par switchMap est bien désabonné.

Conclusion
takeUntilDestroyed est un opérateur très utile pour éviter les fuites mémoires dans une application Angular. Cependant, il est important de faire attention à l'ordre des opérateurs quand on l'utilise avec d'autres opérateurs RxJS. En particulier, il est recommandé de placer takeUntilDestroyed après les opérateurs qui créent de nouveaux observables comme switchMap ou mergeMap.