Angular, créer un service réactif avec les Observables

angular reactive observable service

Les Observables sont un concept que l’on retrouve dans le framework Angular. Il est ainsi possible de créer des services Réactifs en utilisant les Observables pour propager plus facilement la mises à jour des données dans les composants qui consomment ces datas. Je vous présente dans cet article comment mettre en place et utiliser un service réactif pour votre application Angular.

Avec Angular, une grande partie des interventions de support que je suis amenée à faire, implique un problème de mises à jour des informations dans le DOM. Tellement courant mais pourtant si facile à résoudre quand on connaît et ose utiliser les Observables pour pallier ce problème. D’autant plus que le framework Angular vous incite à utiliser la programmation réactive puisqu’il intègre de base la librairie ReactiveX.

Pour les plus avancés d’entre vous, vous pouvez même implémenter la librairie NgRx. Je vous expliquerai comment faire cela dans un prochain article consacré exclusivement à NgRx. Mais pour le moment, regardons comment créer un service Angular et mettre une place un système réactif avec les observables.

Un Service Angular pour la gestion des données

Créer un service Angular c’est le point de départ. Si vous foirez cette étape vous allez accumuler les problèmes tout au long du développement de votre projet. Je vous le garantis! Alors je vais simplement rappeler le principe des service dans Angular, cela vous permettra de mieux comprendre l’approche final que je vais vous présenté.

Le principe élémentaire des Services Angular

Comme la dénomination vous le laisse présager, dans le framework Angular, les services servent à propager les données qui seront implémentés dans le DOM via les Components. Rien de plus simple! Et pourtant….

Malgré que le principe soit simple à comprendre, il est parfois compliqué à l’implémenter correctement dans un projet quand on à pas encore l’habitude d’Angular… je dis cela car il suffit de regarder les posts sur Stackoverflow pour se rendre compte du nombre de personne qui ont des problèmes avec les services.

L’erreur du débutant

Bref, une des erreurs les plus courante est d’utiliser les services uniquement pour « wrapper » le module HTTP de Angular. Ainsi l’utilisation des données se fait avec un subscribe() dans le Component. Cela ne sert absolument à rien.

Vous allez vous retrouver avec la logique de traitement des datas dans vos Components au lieu des Services. Grave erreur de débutant qui vous sera fatal tôt ou tard dans le développement de votre projet.

Vous devez absolument implémenter la logique de traitement des données à l’intérieur des services!

Et je vous encourage vivement à utiliser les Observables avec le Pipe Async pour la gestions de l’affichage car cela vas vous éviter le risque de fuite mémoire à cause des subscribe(), je vous expliquerai cela plus loin dans cet article.

ReactiveX et les Observables

Je vois déjà certains d’entre vous qui fronce les sourcils… Mais non pas de panique! Les Observables c’est fun, pratique et super-facile à utiliser! Vous avez aimé les Promises avec Javascript??? Et bien les Observables c’est le stade aux dessus… la cerise sur le cake!

Personnellement, quand mon prof Angular m’a appris ce que c’était que les observables, j’étais aussi sceptique que lorsqu’il m’a parlé de Git… Il faut dire qu’il y a tellement de nouveautés qui nous tombent dessus quand on prend en main un nouvel outil de développement comme Angular, qu’il est vite fatigant de devoir encore apprendre un nouveau truc alors qu’on ne maitrise pas encore la techno pour lequel on passe de nuit blanche à essayer de faire fonctionner quelque chose.

Du coup quand on te remet une couche avec les services Injectables, les Observables et la programmation réactive, nombreux d’entre vous sont tentés d’utiliser de la mauvaise manière les Observables pour vous simplifier les choses… Mais ERREUR!

Vous allez au contraire vous rajouter des difficultés dont vous ne soupçonnez même pas l’existence au moment où vos faites l’erreur de souscrire ou de convertir en promesse les Observables. Ils ne sont pas faits pour cela! Pensez programmation réactive et utilisez les concepts de ce type de programmation au lieu de vouloir tous convertir en fonctionnel.

Alors c’est quoi un Observable?

Je ne vais pas refaire le cours Angular que vous avez déjà fait avec moi ou l’un de mes collègues. Je vais simplement vous schématiser le fonctionnement pour démystifier le concept pour que vous puissiez comprendre la suite de l’article et ainsi implementer des services réactifs dans vos projets.

Perso, j’aime bien représenter la gestion des données en programmation Réactive à du courant électrique et son réseau de distribution. Je trouve que cela se ressemble en plusieurs points. Mais on peut aussi imaginer un réseau de canalisation qui transporte de l’eau cela fonctionne pas mal non plus. Pour cet article je vais utiliser l’exemple de l’électricité.

Donc imaginez le réseau électrique d’une grande ville comme Genève… 🤣🤣🤣
Non ce n’est pas une grande ville mais cela fonctionne pour l’exemple.

Donc à Genève le seul distributeur d’électricité c’est les SIG (monopole oblige) et donc ce sont eux qui distribuent le courant pour tout le canton (oui en Suisse on a déjà un petit pays mais on a décidé de le découper encore en plusieurs petits morceaux que l’on appelle des cantons… il y en a 26 en tous 😅😅).

Les SIG ont mis en pace tous un réseau de distribution qui permet de transporter le courant électrique dans le moindre recoin du canton de Genève. On pourrait comparer cela au réseau de distribution de vos données dans les différents composants de votre application.

Créer un service réactif comme les SIG

Si vous créez un nouveau Component qui a besoin de consommer des informations en provenance d’un fournisseur de data (un service) vous pouvez si vous voulez l’utiliser les Observables pour vous connecter au réseau. À ce moment, vous servez connecté en direct sur le flux d’informations. Si celui-ci vient à changer ou stopper, vous le verrez directement car je vous rappelle, vous être directement connecté au flux. Comme pour le courant électrique, si une coupure survient, vous le constatez immédiatement. C’est le même principe pour les Observables.

Et c’est ce principe qui permet à vos composants de connaitre en temps réel l’état des données que les services Angular propagent.

Nous allons donc voir comment mettre en place dans un service Angular, ce fameux flux de données Observables qui vous permettra de propager et consommer en temps réel les données dans les différents composants de votre application.

Créer un service réactif avec les Observables

Donc on va regarder comment mettre en place ce service réactif avec les Observables pour corriger le problème de propagation de données. J’ai eu envie de vous montrer en premier deux versions SANS les observables et ensuite une troisième version AVEC les Observables. Pour ainsi mieux voir la différence entre les deux principales manières de programmer.

L’exemple que je vais présenter est tout simple. En gros, un « dump component » doit afficher une liste d’utilisateurs. Lors du click sur un des utilisateurs de la liste, un formulaire nous permet de modifier l’email de l’utilisateur sélectionné. Sur le papier rien de compliquer… Mais on va voir que l’exercice peut vite devenir un véritable casse-tête si on ne prend pas le problème par le bon côté.

Donc pour bien que tous le monde comprenne, je vais retracer le comportement basic d’un développeur Angular qui est en cours apprentissage…

Premier tentative

Alors en premier on vas juste utiliser le service pour faire la requête HTTP et récupérer le lots de donnée dans le Component avec un .subscribe().
Et toute la logique de traitement de donnée est placée dans le Component responsable de l’appel de la requête du service. En gros, toute la logic de traitement est dans le Component, ce qui je le rappel, ne doit jamais être fait.

Mais ça fonctionne me direz vous?? Eh bah non! En plus, le problème c’est que la logic est dans un Component. Si dans un autre Component je suis amener à devoir faire une mise à jours, je vais devoir réécrire toute la logique que j’ai déjà écrit une première fois.. vous voyez ou je veux en venir… En plus, vous aller vite tombé sur des problèmes de mise à jour des données…

Bref, je vous ai préparé une petite démo toutes pourri qu’il ne faut JAMAIS reproduire dans vos projet.

Deuxième tentative

Maintenant en deuxième, voici un exemple un peut mieux conçu avec la gestion des données DANS le service mais SANS les observables. Vous pouvez tester l’application et constater que lors de la mis à jour de l’email d’un utilisateur, les données sont bien mises à jour dans le service mais les modifications ne sont pas propagées au composant qui consomme les données du service.

Troisième tentative

On va maintenant regarder la solution pour corriger ce problème en utilisant les Observables. Voici ce que cela donne AVEC les Observables:

On remarque immédiatement que le code ne change pas beaucoup et que maintenant la propagation de la modification fonctionne correctement. Pourquoi??

Explications

Le principal problème vient des Promises. Vous ne devez jamais oublier qu’un Promise n’est exécuté qu’une seule et unique fois.

Dans le deuxième exemple, quand à la ligne n°32 du fichier « app.component.ts » je déclare que « this.users = this._service.users; » au sein d’une promesse. Et bien cette ligne n’est exécutée qu’une seule fois. Si par la suite je change la valeur de « this._service.users », comme il ne s’agit PAS d’un observable, la nouvelle valeur n’est jamais propagée. Voilà la raison du problème. Avec les deux projets l’un à côté de l’autre on distingue bien la différence et la mise en place qui n’est vraiment pas compliquée.

Cette solution permet de maintenir les données au niveau du service, sans donner l’accès direct au lot de données. On peut ainsi les consommer uniquement via un Observable public qui retourne le contenu du lot de données privées du service. Cela permet de s’assurer que l’instance du lot de données est bien unique. Les modifications et mises à jour des données seront donc propagées correctement à travers les different composants qui seront branchés sur le service.

Subscribe’s hell / Do not subscribe!!

Vous remarquerez aussi que le code ne contient aucun « subscribe ». Je me content de binder dans le HTML les Observables avec le « Pipe async » de Angular qui permet de « subscribe » et « unsubscribe » à la volée dans le template. On évite ainsi tous risque de « fuite mémoire » liée à une mauvaise utilisation des Observables et subscribes.

Conclusion

Vous n’avez donc plus d’excuse pour ne pas utiliser les Observables avec vos service Angular. Cela va tellement vous faciliter le travail. Alors maintenant quand vous me demanderez: « Pourquoi le données de change pas dans mon projet Angular« …, je vous répondrai: « Les Observables… » Ahahah!

Pour ceux qui veulent aller plus loin avec la programmation Réactive, je vais comme expliqué au début de cet article vous mettait en ligne prochainement un article entièrement consacré à la programmation Réactive avec la librairie NgRx.

En attendant, je vous laisse consulter les autres articles traitant du même sujet dans la section Angular.

Tu as besoin de support pour ton projet?
Je t’invite à te rendre sur le lien suivant pour définir ensemble une solution de support qui te convienne.

Donne moi ton avis

Tu n’as pas compris l’explication ou les exemples? Tu as un avis ou une approche différente de celle que je présente dans cet article ? Ecris moi dans le commentaires pour que l’on en discute, je te répond avec plaisir.

5 thoughts on “Angular, créer un service réactif avec les Observables

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *