<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Clara Belair</title>
    <description>The latest articles on DEV Community by Clara Belair (@clarabelair).</description>
    <link>https://dev.to/clarabelair</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F607057%2Fb7123ae0-f420-486a-ab0c-8511e67c1bc4.jpeg</url>
      <title>DEV Community: Clara Belair</title>
      <link>https://dev.to/clarabelair</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/clarabelair"/>
    <language>en</language>
    <item>
      <title>Gestion des erreurs RXJS -NGRX</title>
      <dc:creator>Clara Belair</dc:creator>
      <pubDate>Fri, 09 Apr 2021 12:28:42 +0000</pubDate>
      <link>https://dev.to/stack-labs/gestion-des-erreurs-rxjs-ngrx-3kci</link>
      <guid>https://dev.to/stack-labs/gestion-des-erreurs-rxjs-ngrx-3kci</guid>
      <description>&lt;p&gt;Dans un projet frontend, lorsqu'on fait un appel HTTP, il ne faut pas oublier la gestion des cas d'erreurs. Un appel HTTP peut être en erreur pour diverses raisons, on peut citer : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;un serveur est inaccessible : le backend est "tombé" à cause d'une erreur interne par exemple&lt;/li&gt;
&lt;li&gt;un timeout si la requête prend plus d'un certain temps à répondre&lt;/li&gt;
&lt;li&gt;une erreur renvoyée par le backend avec un message spécifique : l'utilisateur n'a pas le droit d'accéder à cette ressource par exemple&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dans chaque cas, si le frontend ne gère pas ces erreurs, on se retrouve avec une application qui fonctionne mal ou, dans le pire des cas, plus du tout.&lt;/p&gt;

&lt;p&gt;Dans cet article, je vais vous présenter la façon de gérer vos erreurs lors d'un appel HTTP pour un projet Angular. On verra d'abord la gestion des erreurs dans un &lt;code&gt;subscribe&lt;/code&gt;, puis la gestion des erreurs dans un &lt;code&gt;effect&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Prenons l'exemple d'un service &lt;code&gt;HobbitsService&lt;/code&gt; et de la méthode &lt;code&gt;findHobbits&lt;/code&gt; qui fait un appel HTTP pour retourner un observable d'une liste d'Hobbits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HobbitsService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;findHobbits&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hobbit&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hobbit&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api/hobbits&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On veut afficher la liste des Hobbits, et pendant que la requête HTTP est en cours, on affiche un loader à l'utilisateur.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gérer les erreurs dans un &lt;code&gt;subscribe&lt;/code&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Exemple d'une erreur non traitée
&lt;/h3&gt;

&lt;p&gt;Dans le composant &lt;code&gt;HobbitsComponent&lt;/code&gt; une liste d'Hobbits est récupérée à l'initialisation du composant. Un loader est affiché lorsque le booléen &lt;code&gt;isLoading&lt;/code&gt; est à &lt;code&gt;true&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HobbitsComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;hobbits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Hobbit&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HobbitsService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findHobbits&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hobbits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Hobbit&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hobbits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hobbits&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Que se passe-t-il si l'appel  &lt;code&gt;findHobbits&lt;/code&gt; échoue ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Le loader va être affiché, sans s'arrêter, alors que l'appel est terminé. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pourquoi ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La gestion du statut du loader est placé dans la fonction &lt;code&gt;NEXT&lt;/code&gt; du &lt;code&gt;subscribe&lt;/code&gt;. Quand une erreur survient, on ne passe pas dans &lt;code&gt;NEXT&lt;/code&gt; mais dans la fonction &lt;code&gt;ERROR&lt;/code&gt; du &lt;code&gt;subscribe&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  NEXT, ERROR, COMPLETE : les 3 fonctions d'un &lt;code&gt;subscribe&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;subscribe&lt;/code&gt; a 3 fonctions optionnelles : NEXT, ERROR, COMPLETE.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findHobbits&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si l'appel HTTP &lt;strong&gt;réussit&lt;/strong&gt;, on voit les logs suivant :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Next&lt;/span&gt;
&lt;span class="nx"&gt;Completed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En cas de succès, la valeur est émise dans la fonction &lt;code&gt;NEXT&lt;/code&gt;. Puis l'observable se ferme et il passe dans la fonction &lt;code&gt;COMPLETE&lt;/code&gt;. C'est la fin du lifecycle de l'observable, aucune erreur n'a été émise.&lt;/p&gt;

&lt;p&gt;Si l'appel HTTP &lt;strong&gt;échoue&lt;/strong&gt;, on voit les logs suivant :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En cas d'erreur, aucune valeur n'est émise dans la fonction &lt;code&gt;NEXT&lt;/code&gt;. On passe dans la fonction &lt;code&gt;ERROR&lt;/code&gt;, c'est la fin du lifecycle de l'observable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A savoir :&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Un appel HTTP est un observable qui "complete" après avoir émit une valeur. On a alors deux "chemins" possibles : &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcowlhu1tsys9zu43l78z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcowlhu1tsys9zu43l78z.png" alt="image" width="565" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On ne peut pas être dans un &lt;code&gt;COMPLETE&lt;/code&gt; et &lt;code&gt;ERROR&lt;/code&gt; dans le lifecycle d'un observable, c'est soit l'un, soit l'autre. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pour résoudre le problème
&lt;/h3&gt;

&lt;p&gt;Pour gérer l'affichage du loader en cas d'erreur, on va traiter son état dans la fonction &lt;code&gt;NEXT&lt;/code&gt; et dans la fonction &lt;code&gt;ERROR&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HobbitsComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;hobbits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Hobbit&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HobbitsService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findHobbits&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hobbits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Hobbit&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hobbits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hobbits&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si l'appel HTTP réussit ou échoue, on aura le booléen &lt;code&gt;isLoading&lt;/code&gt; à &lt;code&gt;false&lt;/code&gt; et donc on n'aura plus le loader affiché à l'infini.&lt;/p&gt;

&lt;h3&gt;
  
  
  Traiter ou logger l'erreur
&lt;/h3&gt;

&lt;p&gt;Dans le cas où on veut utiliser l'erreur pour debugger ou pour afficher un message précis à l'utilisateur par exemple, on peut utiliser l'erreur retournée comme ceci :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findHobbits&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Gestion les erreurs dans un &lt;code&gt;effect&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Pour gérer vos effets de bord, par exemple vos appels backends, vous pouvez également utiliser la librarie &lt;a href="https://ngrx.io/" rel="noopener noreferrer"&gt;NGRX&lt;/a&gt; et les &lt;a href="https://ngrx.io/guide/effects" rel="noopener noreferrer"&gt;effects&lt;/a&gt;. Personnellement c'est la manière dont je gère ces appels. Je ne donne pas la responsabilité au composant de récupérer les données.&lt;/p&gt;

&lt;p&gt;L'action &lt;code&gt;loadHobbits&lt;/code&gt; met un booléen &lt;code&gt;isLoading&lt;/code&gt; à &lt;code&gt;true&lt;/code&gt; dans le store. L'action &lt;code&gt;loadHobbitsSuccess&lt;/code&gt; passe ce booléen à &lt;code&gt;false&lt;/code&gt; et enregistre la liste des Hobbits dans le store. Le loader est affiché si le booléen &lt;code&gt;isLoading&lt;/code&gt; est à &lt;code&gt;true&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Exemple sans gestion d'erreur
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HobbitsEffects&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;loadHobbits$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actions$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;ofType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loadHobbits&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nf"&gt;concatMap&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findHobbits&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;hobbits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Hobbit&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;loadHobbitsSuccess&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;hobbits&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;actions$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Actions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HobbitsService&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Que se passe-t-il si l'appel  &lt;code&gt;findHobbits&lt;/code&gt; échoue ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Le loader va être affiché, sans s'arrêter, alors que l'appel est terminé. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pourquoi ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Seul l'action &lt;code&gt;loadHobbitsSuccess&lt;/code&gt; met le booléen &lt;code&gt;isLoading&lt;/code&gt; à &lt;code&gt;false&lt;/code&gt;. Or, en cas d'erreur, on ne passe pas dans le &lt;code&gt;map&lt;/code&gt; qui suit l'appel HTTP. Il faudrait attraper l'erreur à l'aide de l'opérateur &lt;code&gt;catchError&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;catchError&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;L'opérateur &lt;code&gt;catchError&lt;/code&gt; va permettre, comme son nom l'indique, d'attraper l'erreur et de retourner un nouvel observable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findHobbits&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="cm"&gt;/*SUCCESS*/&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/*ERROR*/&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pour résoudre le problème
&lt;/h3&gt;

&lt;p&gt;On va créer une nouvelle action &lt;code&gt;loadHobbitsError&lt;/code&gt; qui va permettre dans notre exemple de mettre le booléen &lt;code&gt;isLoading&lt;/code&gt; à &lt;code&gt;false&lt;/code&gt; et donc d'arrêter d'afficher le loader en cas d'erreur.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HobbitsEffects&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;loadHobbits$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actions$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;ofType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loadHobbits&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nf"&gt;concatMap&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findHobbits&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;hobbits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Hobbit&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;loadHobbitsSuccess&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;hobbits&lt;/span&gt; &lt;span class="p"&gt;})),&lt;/span&gt;
          &lt;span class="nf"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;loadHobbitsError&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;actions$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Actions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HobbitsService&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;A savoir :&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Si vous êtes sur une version antérieure à la version 8  d'&lt;code&gt;NGRX&lt;/code&gt;,  en cas d'erreur "non attrapée" dans l'observable principal à l'aide d'un &lt;code&gt;catchError&lt;/code&gt;, l'&lt;code&gt;effect&lt;/code&gt; est &lt;code&gt;complete&lt;/code&gt;.  Depuis la version 8, si aucune erreur est "attrapée" dans l'observable principal, l'&lt;code&gt;effect&lt;/code&gt; se resouscrit avec une limite maximum d'erreurs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Appels multiples
&lt;/h3&gt;

&lt;p&gt;En cas d'appels multiples, on peut choisir de retourner un observable avec des données pour gérer les cas d'appels qui ont échoués.&lt;/p&gt;

&lt;p&gt;Dans l'exemple ci-dessous, on a une liste d'ids d'Hobbits donnée par l'action &lt;code&gt;loadHobbitsBeers&lt;/code&gt;. &lt;br&gt;
Pour chaque id d'Hobbit, on fait un appel HTTP via &lt;code&gt;favoriteBeersByHobbitId&lt;/code&gt; qui va retourner une liste de string qui correspond aux bières préférées d'un Hobbit donné. &lt;br&gt;
Ces appels sont effectués en parallèles, et si l'un d'eux échoue, on enregistre l'id du Hobbit, ainsi que la bière &lt;code&gt;Prancing Pony's Ale&lt;/code&gt; par défaut. Ainsi, les appels qui ont échoué sont traités avec des données par défaut.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HobbitsEffects&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;loadHobbitsDetails$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actions$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;ofType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loadHobbitsBeers&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nf"&gt;mergeMap&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;hobbitsIds&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;forkJoin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;hobbitsIds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hobbitId&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;favoriteBeersByHobbitId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hobbitId&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;beers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hobbitId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nx"&gt;beers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="p"&gt;})),&lt;/span&gt;
              &lt;span class="nf"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
                &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hobbitId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="na"&gt;beers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`Prancing Pony's Ale`&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
              &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;hobbitsBeers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HobbitsBeers&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;loadHobbitsBeersSuccess&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;hobbitsBeers&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;actions$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Actions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HobbitsService&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Traiter ou logger l'erreur
&lt;/h3&gt;

&lt;p&gt;Dans le cas où on veut utiliser l'erreur pour debugger ou pour afficher un message précis à l'utilisateur par exemple, on peut utiliser l'erreur retournée comme ceci :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hobbitsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findHobbits&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;hobbits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Hobbit&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="cm"&gt;/*SUCCESS*/&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nf"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ERROR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/*ERROR*/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>angular</category>
      <category>rxjs</category>
      <category>ngrx</category>
    </item>
    <item>
      <title>Git au quotidien : les seules commandes que j'utilise vraiment</title>
      <dc:creator>Clara Belair</dc:creator>
      <pubDate>Fri, 09 Apr 2021 12:28:20 +0000</pubDate>
      <link>https://dev.to/stack-labs/git-au-quotidien-les-seules-commandes-que-j-utilise-vraiment-3g74</link>
      <guid>https://dev.to/stack-labs/git-au-quotidien-les-seules-commandes-que-j-utilise-vraiment-3g74</guid>
      <description>&lt;p&gt;Je ne suis pas une experte Git, je ne connais pas toutes les commandes, mais depuis quelques années, j'ai une routine et quelques commandes que j'utilise au quotidien. Ces commandes me permettent de gérer 95% de mes besoins.&lt;/p&gt;

&lt;p&gt;Avec seulement &lt;strong&gt;7 commandes&lt;/strong&gt;, je peux gérer mon projet au quotidien. Voici la liste des commandes que je vais présenter à travers mon workflow de développement :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git fetch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git checkout&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git branch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git add&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git commit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git rebase&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Démarrer mon développement
&lt;/h2&gt;

&lt;p&gt;Je présente deux façons de démarrer mon développement. Je vais commencer par GitLab, un outil ultra répandu, que j'ai toujours connu via mes différentes expériences, chez les petits comme chez les gros clients. Il m'est arrivé de démarrer mon développement sans passer par GitLab, donc je présenterai également cette deuxième option.&lt;/p&gt;

&lt;p&gt;La branche principale de développement de votre projet peut s'appeler &lt;code&gt;master&lt;/code&gt;, &lt;code&gt;dev&lt;/code&gt;, &lt;code&gt;main&lt;/code&gt;... Cela dépend de votre projet, et peut importe son nom, c'est la branche sur laquelle toute l'équipe fait partir ses branches pour faire son développement. Dans mon exemple, la branche principale de développement s'appelle &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas 1 : je démarre mon développement via GitLab
&lt;/h3&gt;

&lt;p&gt;Quand je démarre un développement, je créé ma branche à partir de l'issue GitLab, il y a un bouton pour créer une branche, et ça la rattachera à votre issue. Ici mon issue s'appelle : "Add new feature", et la branche va s'appeler automatiquement &lt;code&gt;add-new-feature&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Une fois la branche créée via GitLab, je veux tout simplement la récupérer et me placer sur cette branche.&lt;/p&gt;

&lt;h4&gt;
  
  
  Récupération de ma branche
&lt;/h4&gt;

&lt;p&gt;Je récupère ma branche en local en faisant : &lt;/p&gt;

&lt;p&gt;&lt;code&gt;git fetch&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Je peux voir dans ma console, le nom de ma branche apparaître.&lt;/p&gt;

&lt;h4&gt;
  
  
  Se déplacer sur ma branche
&lt;/h4&gt;

&lt;p&gt;Pour commencer mon développement, je vais me déplacer sur ma branche. Je fais cette commande : &lt;/p&gt;

&lt;p&gt;&lt;code&gt;git checkout add-new-feature&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas 2 : je démarre mon développement à la mano
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Récupération des modifications du projet
&lt;/h4&gt;

&lt;p&gt;Je fais la commande suivante :&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git fetch&lt;/code&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  Se déplacer sur la branche principale
&lt;/h4&gt;

&lt;p&gt;Je me place sur la branche principale de développement de mon projet. Pour me déplacer, j'utilise &lt;code&gt;git checkout&lt;/code&gt;. Ici, la branche principale de développement de mon projet s'appelle &lt;code&gt;main&lt;/code&gt;, donc je fais : &lt;/p&gt;

&lt;p&gt;&lt;code&gt;git checkout main&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Écraser la branche principale pour la mettre à jour
&lt;/h4&gt;

&lt;p&gt;J'écrase la branche &lt;code&gt;main&lt;/code&gt; locale par la branche distante &lt;code&gt;main&lt;/code&gt; : &lt;/p&gt;

&lt;p&gt;&lt;code&gt;git reset --hard origin/main&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A partir de ce moment là, je sais que la branche &lt;code&gt;main&lt;/code&gt; locale est la même que la branche distante. Je m'assure ainsi de créer ma branche à partir de la branche principale à jour.&lt;/p&gt;

&lt;h4&gt;
  
  
  Création de ma branche et se déplacer sur celle-ci
&lt;/h4&gt;

&lt;p&gt;Je veux créer ma branche à partir de &lt;code&gt;main&lt;/code&gt; pour faire mon développement et me déplacer sur la branche créée. Je veux appeler ma branche &lt;code&gt;add-new-feature&lt;/code&gt;, je vais donc faire la commande suivante : &lt;/p&gt;

&lt;p&gt;&lt;code&gt;git checkout -b add-new-feature&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  En cours de développement
&lt;/h2&gt;

&lt;p&gt;Je développe sur ma branche, et une fois tout ou partie de mon développement terminé je fais les commandes suivantes :&lt;/p&gt;

&lt;h3&gt;
  
  
  J'ajoute mes modifications
&lt;/h3&gt;

&lt;p&gt;J'ajoute toutes mes modifications, je fais : &lt;br&gt;
&lt;code&gt;git add .&lt;/code&gt; &lt;br&gt;
ou&lt;br&gt;
&lt;code&gt;git add -A&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Cas 1 : je commit pour la première fois
&lt;/h3&gt;

&lt;p&gt;Je créé mon commit avec ce message &lt;code&gt;feat(example): add new feature&lt;/code&gt;. Je fais la commande suivante : &lt;br&gt;
&lt;code&gt;git commit -m "feat(example): add new feature"&lt;/code&gt;&lt;br&gt;
ou&lt;br&gt;
&lt;code&gt;git commit&lt;/code&gt; (va m'ouvrir l'éditeur de mon choix, vim par défaut)&lt;/p&gt;

&lt;p&gt;Si le &lt;strong&gt;Conventional-Changelog&lt;/strong&gt; ne vous dit rien, voici un &lt;a href="https://blog.stack-labs.com/code/devops_conventional_changelog/" rel="noopener noreferrer"&gt;article pour vous&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Cas 2 : j'ajoute des modifications à mon commit précédent
&lt;/h3&gt;

&lt;p&gt;Si je veux ajouter un développement supplémentaire sur ma branche,  je travaille en général avec un seul commit pour mon développement, donc j'utilise &lt;code&gt;git commit --amend&lt;/code&gt; :&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git commit --amend&lt;/code&gt; &lt;br&gt;
ou&lt;br&gt;
 &lt;code&gt;git commit --amend --no-edit&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Je ne travaille pas avec des commits intermédiaire du genre :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat(example): add something
feat(example): delete something
feat(example): update something else
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour ensuite "squash" ces commits pour avoir 1 seul commit :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat(example): add new feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Je fais un seul commit, mon commit final, et j'&lt;code&gt;amend&lt;/code&gt; ce commit pour n'avoir qu'un seul commit qui sera mergé sur la branche de développement. C'est une question d'habitude et de préférence.&lt;/p&gt;

&lt;h2&gt;
  
  
  A la fin de mon développement
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Prérequis si vous créez vos branches en local : configurez votre git avec cette commande pour ne pas avoir à préciser à chaque fois l'upstream : &lt;code&gt;git config --global push.default current&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Je pousse mes modifications
&lt;/h3&gt;

&lt;p&gt;Je fais cette commande pour pousser mon développement :&lt;br&gt;
&lt;code&gt;git push&lt;/code&gt;&lt;br&gt;
ou&lt;br&gt;
&lt;code&gt;git push --force-with-lease&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Si vous n'êtes pas familier avec l'option &lt;code&gt;--force-with-lease&lt;/code&gt;, je vous recommande &lt;a href="https://blog.stack-labs.com/code/git_force_with_lease/" rel="noopener noreferrer"&gt;cet article&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mise à jour de ma branche par rapport à la branche principale
&lt;/h3&gt;

&lt;p&gt;Dans le cas où la branche principale de développement à évoluée par rapport à ma branche de développement, je dois faire un &lt;code&gt;git rebase&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Je récupère toutes les modifications faites par les autres personnes de mon projet : &lt;/p&gt;

&lt;p&gt;&lt;code&gt;git fetch&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Je mets à jour ma branche par rapport à &lt;code&gt;main&lt;/code&gt; (la branche principale).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git rebase origin/main&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Je gère les conflits éventuels via mon IDE pour plus de simplicité. Vous avez également des outils Git qui permettent de gérer les conflits plus facilement.&lt;/p&gt;

&lt;p&gt;Et ensuite je push quand j'ai terminé mon rebase :&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git push --force-with-lease&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;J'utilise également le rebase interactive &lt;code&gt;-i | --interactive&lt;/code&gt; pour certaines situations. C'est une option que je conseille de regarder même si je ne l'utilise qu'occasionnellement (&lt;a href="https://git-scm.com/docs/git-rebase" rel="noopener noreferrer"&gt;la doc du rebase&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Les commandes supplémentaires
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Utilisées occasionnellement
&lt;/h3&gt;

&lt;p&gt;Quand je veux voir l'historique des commits sur une branche :&lt;br&gt;
&lt;code&gt;git log&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Quand je veux voir mes modifications en cours non commités : &lt;br&gt;
&lt;code&gt;git status&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Quand je veux sauvegarder un "brouillon" de mon développement en cours sur une branche :&lt;br&gt;
&lt;code&gt;git stash&lt;/code&gt;&lt;br&gt;
Quelques exemples de &lt;code&gt;stash&lt;/code&gt; sont listés &lt;a href="https://git-scm.com/docs/git-stash/fr#_exemples" rel="noopener noreferrer"&gt;ici&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Utilisées rarement
&lt;/h3&gt;

&lt;p&gt;Quand je démarre sur un nouveau projet : &lt;br&gt;
&lt;code&gt;git clone&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Quand je définis mon nom d'auteur et l'email associé :&lt;br&gt;
&lt;code&gt;git config --global user.name "Clara Belair"&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git config --global user.email clara.belair@example.com&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pourquoi je préfère &lt;code&gt;git fetch&lt;/code&gt; à &lt;code&gt;git pull&lt;/code&gt; pour récupérer les modifications distantes ?
&lt;/h2&gt;

&lt;p&gt;On me pose souvent la question pourquoi je fais un &lt;code&gt;git fetch&lt;/code&gt; au lieu d'un &lt;code&gt;git pull&lt;/code&gt;. Attention, ce ne sont pas des commandes équivalentes. Si vous faites un &lt;code&gt;git pull&lt;/code&gt;, par défaut, il y a un &lt;code&gt;merge&lt;/code&gt; qui est fait juste après le &lt;code&gt;fetch&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Voici la description de &lt;code&gt;git pull&lt;/code&gt; (&lt;a href="https://git-scm.com/docs/git-pull/fr" rel="noopener noreferrer"&gt;https://git-scm.com/docs/git-pull/fr&lt;/a&gt;) :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Intègre les modifications d’un dépôt distant dans la branche actuelle. Dans son mode par défaut, &lt;code&gt;git pull&lt;/code&gt; est l’abréviation de &lt;code&gt;git fetch&lt;/code&gt; suivi de &lt;code&gt;git merge FETCH_HEAD&lt;/code&gt;."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pour éviter toute mauvaise surprise, je conseille donc de faire un &lt;code&gt;git fetch&lt;/code&gt; pour récupérer les modifications distantes. Ou alors soyez conscient des commandes exécutées derrière &lt;code&gt;git pull&lt;/code&gt; par défaut et de leurs conséquences sur votre branche actuelle.&lt;/p&gt;

</description>
      <category>git</category>
    </item>
  </channel>
</rss>
