# Le cycle de vie d'un composant en Angular : que faut t-il retenir avec la renaissance du framework ?

Depuis la sortie de la version 17 du framework Angular, on parle de la renaissance de Angular. Il y a eu beaucoup de changements majeurs depuis la version 16 du framework pour préparer le terrain à cette renaissance. Ces changements majeurs ont rendu le framework davantage attractif et performant. Dans cet article, nous nous intéresserons au cycle de vie d’un composant en Angular afin de mieux comprendre quelques subtilités d’une part et d’autre part, quels sont les changements qui y ont été apportés.

Avant d’entrer dans le vif du sujet, nous essaierons de comprendre ce qu’est le cycle de vie d’un composant.

Le cycle de vie d’un composant en général, peu importe la technologie utilisée représente les différentes étapes par lesquelles le composant passe depuis la création jusqu’à la destruction. En effet, ce processus est très similaire à la vie d’un être humain par exemple. L’homme naît, grandit, vieillit et meurt. C’est comme cela, il faut voir le cycle de vie d’un composant également. En Angular, ces différentes phases sont perceptibles à travers les différentes méthodes que le framework nous offre. Le cycle de vie d'un composant est étroitement lié à la façon dont Angular vérifie les modifications apportées à nos composants au fil du temps. Notre prochain objectif sera décortiquer une à une ces méthodes afin de rendre le plus accessible possible à la compréhension des uns et des autres.

1. **La méthode** `constructor()` **:**
    

Le framework Angular est basé sur le langage TypeScript. Chaque composant Angular n’est rien d’autre qu’une classe TypeScript. Lorsqu’on parle de classe, on parle de la programmation orientée objet. Ainsi, la première méthode qui s’exécute dans une classe c’est le constructeur de la classe qui est `constructor`.

Dès que le framework Angular crée une instance de notre composant à l’exécution de notre application, c’est la méthode `constructor` qui s’exécute en premier. On appelle cette étape du cycle de vie d’un composant Angular : ***création***.

2. **La méthode** `ngOnChanges()` **:**
    

Après la phase de création que nous venons de voir précédemment, la prochaine étape c’est la phase : ***détection de changements*** (***change detection*** en anglais). La première méthode de cette phase est la méthode `ngOnChanges()`.

La méthode ngOnChanges s'exécute après que les entrées du composant ont été modifiées. En effet, pour jauger de la pertinence de cette méthode et comprendre comment elle fonctionne, il faut la tester sur un composant ayant des `inputs`.

En Angular, lorsqu’on décide de passer des informations d’un composant A parent vers un composant B enfant, on passe par des `inputs` au niveau du composant enfant. Lorsque le composant parent A met à jour les inputs du composant enfant B, la méthode `ngOnChanges()` se déclenche et ce à chaque nouvelle mise à jour des `inputs` .

3. **La méthode** `ngOnInit()` **:**
    

La deuxième méthode de la phase de détection de changement du cycle de vie d’un composant Angular est la méthode `ngOnInit()`.

La méthode `ngOnInit()` s'exécute après qu'Angular ait initialisé toutes les entrées (*inputs*) des composants avec leurs valeurs initiales. La méthode `ngOnInit()` d'un composant s'exécute exactement une fois.

Cette étape se produit avant que le *template HTML* du composant ne soit initialisé. Cela signifie que vous pouvez mettre à jour l'état du composant en fonction de ses valeurs d'entrée (*input*) initiales.

4. **La méthode** `ngDoCheck()`
    

Juste après l’exécution de la méthode `ngOnInit()`, notre composant demeure toujours dans la phase de détection de changement à travers l’exécution de la méthode `ngDoCheck()` .

La première fois que la méthode `ngDoCheck()` s’exécute c’est juste après l’exécution de la méthode `ngOnInit()`. Ensuite, `ngDoCheck()` s'exécute avant chaque vérification par Angular des changements apportés au niveau du *template HTML* de notre composant.

Cette méthode s'exécute très fréquemment et peut avoir un impact significatif sur les performances de votre page. Ainsi, évitons d’utiliser cette méthode autant que possible, ne l'utilisons que lorsque nous n’avons vraiment pas d'autre alternative.

5. **La méthode** `ngAfterContentInit()`
    

Lorsque dans notre composant Angular, nous interagissons avec des `content queries` à savoir `@ContentChild()` ou `@ContentChildren()` , la méthode `ngAfterContentInit()` s'exécute une seule fois lorsque tous les enfants imbriqués (`content queries`) dans le composant ont été initialisés.

Nous pouvons donc accéder à l'état initialisé de nos queries mais toute tentative de modification de l'état dans cette méthode entraîne une erreur `ExpressionChangedAfterItHasBeenCheckedError`.

La méthode `ngAfertContentInit()` lorsqu’elle est définie, s’exécute juste après le `ngDoCheck()` .

Pour ceux qui n’ont aucune idée de ce qu’est une `content query`, voici un exemple :

```typescript
@Component({
  selector: 'custom-toggle',
  ...
  template: `<div> 
             <ng-content></ng-content> 
             </div>`
})
export class CustomToggle {
  text: string;
}
@Component({
  selector: 'custom-expando',
  ...
  template: `<div> 
             <ng-content></ng-content> 
             </div>`
})
export class CustomExpando {
  @ContentChild(CustomToggle) toggle: CustomToggle;
  ngAfterContentInit() {
    console.log(this.toggle.text);
  }
}
@Component({
  selector: 'user-profile',
  template: `
    <custom-expando>
      <custom-toggle>Show</custom-toggle>
    </custom-expando>
  `
})
export class UserProfile { }
```

> Le composant `custom-toggle` est projecté dans le composant `custom-expando` à travers la directive `ng-content`.
> 
> Le composant `custom-toggle` à son tour est capable de projecter du contenu d’où le texte `Show` à l’intérieur des balises `custom-toggle` lors de son utilisation dans le template du composant `user-profile`.
> 
> Lorsqu’on parle de `content query`, il faut penser à la `projection de contenue` avec la directive `ng-content`.

6. **La méthode** `ngAfterContentChecked()` **:**
    

La méthode `ngAfterContentChecked()` est étroitement liée à la méthode `ngAfterContentInit()`. En effet, lorsque toutes nos `content queries` sont initialisées, la méthode `ngAfterContentChecked()` s’exécute pour marquer ces `content queries` comme étant `checked`. Cela signifie tout simplement que ces `content queries` ont été vérifiées pour déterminer si des changements ont eu lieu à leurs différents niveaux.

Cette méthode s'exécute très fréquemment et peut avoir un impact significatif sur les performances de votre page. Ainsi, évitons d’utiliser cette méthode autant que possible, ne l'utilisons que lorsque nous n’avons vraiment pas d'autre alternative.

Bien que nous puissions accéder à l'état mis à jour des `content queries` ici, toute tentative de modification d'un état dans cette méthode entraîne une erreur `ExpressionChangedAfterItHasBeenCheckedError` (`ExpressionChangedAfterItBeenChecked`).

7. **La méthode** `ngAfterViewInit()` **:**
    

Tout comme nous l’avons vu précédemment avec la méthode `ngAfterContentInit()` , la méthode `ngAferViewInit()` aussi s’exécute juste après la méthode `ngDoCheck()` .

En effet, pendant que la méthode `ngAfterContentInit()` est utilisée pour les `content queries` , la méthode `ngAfterViewInit()` est utilisée pour les view queries (`@ViewChild()` , `@ViewChildren()`.

La méthode `ngAfterViewInit()` s'exécute une seule fois lorsque tous les enfants imbriqués (`view queries`) dans le composant ont été initialisés.

Nous pouvons donc accéder à l'état initialisé de nos `view queries` mais toute tentative de modification de l'état dans cette méthode entraîne une erreur `ExpressionChangedAfterItHasBeenCheckedError`.

Pour ceux qui n’ont aucune idée de ce qu’est une view query, voici un exemple :

```typescript
@Component({
  selector: 'custom-card-header',
  ...
})
export class CustomCardHeader {
  text: string;
}
@Component({
  selector: 'custom-card',
  template: '<custom-card-header>Visit sunny California!</custom-card-header>',
})
export class CustomCard {
  @ViewChild(CustomCardHeader) header: CustomCardHeader;
  ngAfterViewInit() {
    console.log(this.header.text);
  }
}
```

> Dans le composant parent `CustomCard`, on essaie de récupérer le composant enfant `CustomCardHeader`.
> 
> Lorsqu’on parle de `view query`, il faut penser à un `composant enfant` qu’on essaie de récupérer depuis un `composant parent` dynamiquement.

8. **La méthode** `ngAfterViewChecked()` **:**
    

La méthode `ngAfterViewChecked()` suit la même logique que la méthode `ngAfterContentChecked()` . Tout comme la méthode `ngAfterContentChecked()` est étroitement liée à la méthode `ngAfterContentInit()` , la méthode `ngAfterViewChecked()` est aussi liée à la méthode `ngAfterViewInit()` .

En effet, lorsque toutes nos `view queries` sont initialisées, la méthode `ngAfterViewChecked()` s’exécute pour marquer ces `view queries` comment étant `checked`. Cela signifie tout simplement que ces `view queries` ont été vérifiées pour déterminer si des changements ont eu lieu à leurs différents niveaux.

Bien que nous puissions accéder à l'état mis à jour des `view queries` ici, toute tentative de modification d'un état dans cette méthode entraîne une erreur `ExpressionChangedAfterItHasBeenCheckedError` (`ExpressionChangedAfterItBeenChecked`).

9. **Les méthodes** `afterRender()` **et** `afterNextRender()`**:**
    

Les méthodes `afterNextRender()` et `afterRender()` font parties des nouvelles méthodes ajoutées au cycle de vie d’un composant Angular depuis la version 16.2 du framework.

La méthode `afterRender()` se déclenche à chaque fois que ***tous les composants sont chargés dans le DOM***\*.\*

Quant à la méthode `afterNextRender()`, elle se déclenchera la prochaine fois que ***tous les composants seront chargés dans le DOM*** mais une seule fois\*.\*

10. **La méthode** `ngOnDestroy()` **:**
    

La méthode `ngOnDestroy` s'exécute une fois juste avant la destruction d'un composant. Angular détruit un composant lorsqu'il n'est plus affiché sur la page, par exemple lorsqu'il est masqué par un `NgIf` ou lorsqu'on navigue vers une autre page.

En somme, le cycle de vie d’un composant Angular se résume en trois phase à savoir : ***la phase de création***, ***la phase de détection de changements*** et ***le rendering***. La ***phase de rendering*** a été introduite dans le framework à la sortie de la version 16 du framework. Chacune de ces phases fait appel à des méthodes dans lesquelles nous pouvons gérer des traitements au besoin. Il est très important de maîtriser ces phases afin d’assurer la performance de nos composants Angular.

> Pour plus d'informations 👉 [Component Lifecycle](https://angular.dev/guide/components/lifecycle)
