Photo by James Harrison on Unsplash
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 :
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.
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 :
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 :
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 :
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 avezFormControl
vous aurezUntypedFormControl
.
const personForm = new UntypedFormGroup({ firstname: new UntypedFormControl(''), lastname: new UntypedFormControl(''), });
Soit nous le gardons ainsi, soit nous remplaçons par exemple
UntypedFormControl
parFormControl<any>
ouFormControl
tout simplement car par défautFormControl
a un typeany
.
Pour plus d'informations :