Bonjour,

Je travaille actuellement sur un gros projet et pour celà j'ai besoin de travailler avec Firebase et Angular 5, mais je bloque un peu sur la validation des formulaires.
Je vous explique, j'aimerais créer un validateur personnalisé pour vérifier si l'email que l'utilisateur entre est déjà utilisé.
Pour cela, j'ai mis une fonction dans les validateurs personnalisés, jusque là tout va bien, l'erreur s'affiche quand l'email est déjà utilisée, mais c'est lorsque l'on entre un email qui n'est pas utilisé qu'il y'a un problème.

Lorsque je valide le formulaire avec un email déjà utilisé, le formulaire me renvoie le statut : "INVALID", ce qui est tout a fait normal et c'est ce que je recherche, mais lorsque je valide avec un email qui n'est pas dans firestore, il me renvoie aussitôt une erreur m'indiquant que le formulaire est en statut "PENDING", c'est à dire qu'il attends.. Mais attendre quoi ?

Ce que je fais

Je crée mon formControl dans mon template

// inscription.component.html
<mat-step [stepControl]="form">
  <form [formGroup]="form">
    <mat-form-field>
       <input matInput formControlName="email" 
       placeholder="Ton adresse email" required>
       <mat-error *ngIf="email.invalid">
         {{ getErrorMessage(email, 'adresse email', 3, 25) }}
       </mat-error>
    </mat-form-field>
  </form>
</mat-step>

Ma fonction getErrorMessage()

// inscription.component.html
    getErrorMessage(selector: any, element: string, minCharacters: number, maxCharacters: number) {
        return selector.hasError('required') ? 'Tu dois entrer ton ' + element :
        selector.hasError('notunique') ? 'Cette ' + element + ' est déjà utilisée' :
        '';
    }

J'initialise tout ce dont j'ai besoin pour créer le formulaire :

// inscription.component.ts
form: FormGroup;
email = new FormControl('', [
   Validators.required,
   Validators.email,
   Validators.minLength(3),
   Validators.maxLength(25)
   // Fonction pour la vérif de l'email
], this.checkIfEmailExistsInDatabase.bind(this));

Puis je lie mon formControl de l'email dans la fonction "onInit()" :

// inscription.component.ts
    ngOnInit() {
        this.form = new FormGroup({
            email: this.email,
        });
    }

Et enfin... là d'ou viens le "bug" :

// inscription.component.ts
    checkIfEmailExistsInDatabase(control: AbstractControl) {
        return new Promise(resolve => {
            // On vérifie qu'il n'y a pas de document au même nom de ce qu'il y'a dans le formControl
            firebase.firestore().collection('items').where('email', '==', control.value).get()
                .then(snapshot => {
                    snapshot.forEach(doc => {
                        if (!doc.exists) {
                            console.log('L\'email n\'existe pas');
                            resolve(null);
                            // ERREUR : Le statut de la validation reste en "PENDING"
                            // Alors qu'il doit normalement faire passer à l'étape d'après
                        } else {
                            console.log('L\'email existe déjà');
                            resolve({ 'notunique' : true });
                            // Un message d'erreur s'affiche bien et bloque la validation
                        }
                    })
                });
        });
    }

J'avoue que je ne comprends vraiment pas pourquoi le formulaire ne peux pas être validé et je comprends pas d'ou peux venir ce bug, si toutefois il s'agit d'un bug, et comment le réparer.. :?

Si vous avez une idée n'hésitez pas à répondre, et je vous remercierais infiniment de votre aide !

Aucune réponse