• 8 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 31/03/2022

Maintenez l'intégrité des données avec les Validators

Même si la majeure partie de la validation se passe côté serveur, Angular vous permet d'ajouter une première couche de validation de formulaire côté front-end.

Vous allez utiliser les Validators pour mettre en place les champs requis du formulaire de nouveau FaceSnap, ainsi que pour vérifier que l'URL d'image entrée par l'utilisateur correspond à une URL (et non à un texte aléatoire).

Une fois les données validées, vous pourrez terminer l'implémentation de l'ajout du FaceSnap aux données de l'application pour permettre aux utilisateurs de créer leurs propres FaceSnaps !

Validez le formulaire

Ajouter une validation aux formulaires réactifs est plutôt simple : il suffit de les ajouter à la configuration des champs passés à la méthode  group  de FormBuilder.

La première validation que vous allez ajouter est celle qui vérifie que les champs requis contiennent bien des valeurs. Le Validator correspondant est  Validators.required  :

this.snapForm = this.formBuilder.group({
    title: [null, [Validators.required]],
    description: [null, [Validators.required]],
    imageUrl: [null, [Validators.required]],
    location: [null]
});

Pour empêcher l'utilisateur d'envoyer le formulaire s'il n'est pas valable, vous pouvez lier l'attribut  disabled  du bouton d'enregistrement à l'attribut  invalid  du FormGroup – si le formulaire n'est pas valable, le bouton sera désactivé.

Dans le template :

<!-- ... -->
<button type="submit" (click)="onSubmitForm()" [disabled]="snapForm.invalid">Enregistrer</button>
<!-- ... -->

Ainsi, si vous n'entrez rien dans les champs requis :

Bouton désactivé
Bouton désactivé

Vous allez maintenant ajouter un deuxième Validator au champ  imageUrl  pour vérifier que le texte entré par l'utilisateur correspond à une URL – il s'agit de  Validators.pattern  , qui compare la valeur entrée à une expression régulière (RegExp).

Déclarez une variable qui contiendra le pattern  RegExp  :

// ...
snapForm!: FormGroup;
faceSnapPreview$!: Observable<FaceSnap>;
urlRegex!: RegExp;
// ...

Et dans  ngOnInit()  , initialisez-la avec le pattern ci-dessous :

this.urlRegex = /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)/;

Ici vous ne vérifiez pas que l'URL est valable : simplement que le texte ressemble à une URL.

Il ne reste plus qu'à ajouter un deuxième Validator – le Validator pattern – à la configuration du contrôle  imageUrl  :

this.snapForm = this.formBuilder.group({
    title: [null, [Validators.required]],
    description: [null, [Validators.required]],
    imageUrl: [null, [Validators.required, Validators.pattern(this.urlRegex)]],
    location: [null]
});

Si vous testez le formulaire de nouveau, vous verrez que le bouton Enregistrer ne s'active que si le champ URL contient quelque chose qui ressemble à une URL.

Cependant, si vous regardez la console pendant que vous entrez cette URL, vous voyez des erreurs 404 :

Des erreurs 404
Des erreurs 404

Est-ce que vous comprenez pourquoi ces erreurs apparaissent ?

Changez le rythme des émissions

Ces erreurs apparaissent parce que l'aperçu du FaceSnap sous le formulaire reçoit toutes les valeurs intermédiaires de l'URL, et essaie de les attribuer comme sources d'image. Du coup, tant que l'URL n'est pas complète, vous aurez des erreurs 404 ou, pire, des requêtes vers des ressources non souhaitées !

Pour éviter ces requêtes inutiles, vous pouvez modifier le déclenchement de  valueChanges  du formulaire pour émettre uniquement lorsque l'utilisateur change de champ, c'est-à-dire lors du  blur  des différents champs. Pour ceci, vous allez passer un objet de configuration à la méthode  group  :

this.snapForm = this.formBuilder.group({
    title: [null, [Validators.required]],
    description: [null, [Validators.required]],
    imageUrl: [null, [Validators.required, Validators.pattern(this.urlRegex)]],
    location: [null]
}, {
    updateOn: 'blur'
});

Maintenant, les informations entrées dans le formulaire ne sont affichées dans l'aperçu que lorsque l'utilisateur change le focus du formulaire, évitant ainsi les erreurs 404.

Ajoutez le FaceSnap

À vous de jouer !

Avec la validation mise en place, vous pouvez implémenter l'ajout du FaceSnap entré par l'utilisateur.

Vous allez créer une méthode de service qui accepte les informations du formulaire en arguments, et qui ajoutera un FaceSnap valable aux données de l'application. Vous appellerez ensuite cette méthode depuis le component, et vous redirigerez l'utilisateur vers la liste des FaceSnaps après l'enregistrement réussi.

Commencez par la méthode dans FaceSnapsService. Elle doit accepter les valeurs du formulaire, générer un FaceSnap avec les champs requis (notamment avec un Id unique et valable), et ajouter l'objet généré au tableau des FaceSnaps.

Prenez quelques instants pour l'implémenter vous-même, avant de regarder comment je m'y prends.

Suivez mon approche

Voici ma proposition :

addFaceSnap(formValue: { title: string, description: string, imageUrl: string, location?: string }) {
    const faceSnap: FaceSnap = {
        ...formValue,
        snaps: 0,
        createdDate: new Date(),
        id: this.faceSnaps[this.faceSnaps.length - 1].id + 1
    };
    this.faceSnaps.push(faceSnap);
}

Cette méthode :

  • accepte un objet comme argument, qui correspond à l'objet généré par le formulaire ;

  • crée un nouvel objet à partir de l'argument en ajoutant les champs manquants ;

  • ajoute 1 à l' id  du dernier ajouté au tableau pour générer le nouveau, puisque les  id  des FaceSnap sont des entiers croissants ;

  • ajoute le FaceSnap au tableau.

La méthode est prête à être appelée lors de l'envoi du formulaire.

La fonctionnalité souhaitée est que l'utilisateur soit redirigé après l'ajout du FaceSnap. Il faudra donc injecter FaceSnapsService et le Router dans NewFaceSnapComponent, et modifier l'implémentation de la méthode  onSubmitForm()  :

// ...
constructor(private formBuilder: FormBuilder,
            private faceSnapsService: FaceSnapsService,
            private router: Router) { }
// ...
onSubmitForm() {
    this.faceSnapsService.addFaceSnap(this.snapForm.value);
    this.router.navigateByUrl('/facesnaps');
}

Avec cette dernière étape, vous avez un formulaire qui fonctionne, qui est validé, et qui ajoute bien un nouveau FaceSnap à l'application !

En résumé

  • Ajoutez de la validation aux contrôles de vos formulaires en passant des Validators au moment de la configuration du FormGroup.

  • Validators.required  rend un champ du formulaire requis.

  • Validators.pattern  vérifie que le contenu d'un champ correspond à une expression régulière.

Qu'avons-nous appris dans cette partie du cours ?

Dans cette partie du cours, vous avez créé vos premiers formulaires.

  • Vous avez créé un formulaire simple sous forme de formulaire template, en utilisant le two-way binding avec  ngModel  et les références locales aux  NgForm ;

  • Vous avez implémenté un formulaire réactif avec FormBuilder et observé ses changements de valeur via son Observable  valueChanges ;

  • Vous avez mis en place la validation avec les  Validators  et vous avez terminé l'implémentation de la création de nouveaux FaceSnaps.

Dans la prochaine partie du cours, vous apprendrez à générer et envoyer des requêtes HTTP, vous permettant de créer des applications totalement dynamiques ! Avant de découvrir tout cela, je vous invite à faire le quiz suivant – à très vite !

Exemple de certificat de réussite
Exemple de certificat de réussite