# Que se passe t-il avec Angular Reactive Forms à partir de Angular 14 ?

Parmi les nouveautés présentes dans ***la version 14 de Angular***, on observe un changement drastique lié à la gestion des formulaires pilotés par le module `ReactiveFormsModule`. Malheureusement, beaucoup n'y prêtent pas attention et j'ai décidé de mettre davantage la lumière là-dessus.

Jusqu'à ***la version 13 de Angular***, toutes les classes qui entrent dans le processus de la gestion des formulaires n'ont pas de type explicite et sont donc tous de type `any`. Autrement dit, il n'y avait pas de typage fort ce qui va naturellement à l'encontre des principes du langage `TypeScript`, langage utilisé par le framework ***Angular***. Si l'on devrait implémenté un formulaire en ***Angular 13***, voici ce que l'on ferait par exemple :

```typescript
const lastnameControl = new FormControl('');
const firstnameControl = new FormControl('');
```

Comme nous pouvons le remarquer, ***nous n'avons aucun moyen de préciser un type bien explicite à notre contrôleur de champ*** `FormControl`.

> Est-ce qu'il s'agit d'un `FormControl` sur un champ de texte (string), un bouton radio (boolean), un nombre (number), ... ? 🤔
> 
> Nous n'avons aucun moyen d'être sûr du type 🥺

Nous comprenons que ce mode de fonctionnement devient très gênant lorsqu'il s'agit de gérer des formulaires complexes. C'est important de connaître le type de retour de chacun de nos champs et implicitement de nos `FormControl`. Nous rencontrons le même souci avec nos `FormGroup`, nos `AbstractControl` et toutes les instances qui s'y trouvent.

```typescript
const personForm = new FormGroup({
  firstname: new FormControl(''),
  lastname: new FormControl(''),
});
```

Face à cette problématique, ***la core team a décidé d'introduire les formulaires typés à partir de Angular 14***. Nous verrons ensemble les différences qui sont d'ailleurs très flagrantes.

Reprenons l'exemple précédent de nos `FormControl` en implémentant le typage fort. Voici le résultat :

```typescript
const lastnameControl = new FormControl<string | null>('');
const firstnameControl = new FormControl<string | null>('');
```

Poussons plus loin notre curiosité en essayant d'utiliser un `FormGroup` sur notre formulaire :

```typescript
interface IPersonForm {
  firstname: FormControl<string | null>;
  lastname: FormControl<string | null>;
}

const personForm = new FormGroup<IPersonForm>({
  firstname: new FormControl(''),
  lastname: new FormControl(''),
});
```

Il est très évident que la lecture même du code est plus simple et la détection d'erreurs est plus facile. Cela ne fait qu'améliorer le ***Developer Experience*** et facilite la débogage pour nous les développeurs.

Pour finir, vous avez remarqué que le type `null` a été ajouté au niveau des `FormControl`. En effet, lors de l'appel de la méthode `reset()` sur le formulaire nos contrôles nous renverrons `null`.  
Cependant, il y a un moyen d'y remédier :

```typescript
interface IPersonForm {
  firstname: FormControl<string>;
  lastname: FormControl<string>;
}

const personForm = new FormGroup<IPersonForm>({
  firstname: new FormControl('', { nonNullable: true }),
  lastname: new FormControl('', { nonNullable: true }),
});
```

L'attribut `nonNullable` qui est également une nouveauté nous évite ce comportement.

En somme, pour ceux qui ont créé des projets à partir de Angular 14, ne soyez pas surpris par l'obligation du typage fort lors de l'utilisation du module `ReactiveFormsModule`.

> Pour ceux qui font des mises à niveau vers Angular 14 (au minimum) \[`ng update @angular/core`\], vous remarquerez que toutes vos instances sont automatiquement remplacées par : `Untyped` + le nom traditionnel de l'instance.  
> Par exemple si vous avez `FormControl` vous aurez `UntypedFormControl`.
> 
> ```typescript
> const personForm = new UntypedFormGroup({ 
>     firstname: new UntypedFormControl(''), 
>     lastname: new UntypedFormControl(''),  
> });
> ```
> 
> Soit nous le gardons ainsi, soit nous remplaçons par exemple `UntypedFormControl` par `FormControl<any>` ou `FormControl` tout simplement car par défaut `FormControl` a un type `any`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681446283172/b2b5bc11-32b4-43ea-ab75-b29aa5404d0f.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681446800866/cf3aaad9-eafe-4750-b21e-ad80f3de46c1.png align="center")

> Pour plus d'informations :
> 
> 👉 [AbstractControl](https://angular.io/api/forms/AbstractControl)
> 
> 👉 [FormGroup](https://angular.io/api/forms/FormGroup)
> 
> 👉 [FormControl](https://angular.io/api/forms/FormControl)
> 
> 👉 [FormBuilder](https://angular.io/api/forms/FormBuilder)
