Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate a form field asynchronously (after HTTP request) in Angular 2

The idea is to let the user POST the form. And trigger the error returned by the API for set the email field as error if the user is already register.

I use reactive forms with FormBuilder and I trying calling the validator in the subscribe error catcher :

Constructor :

this.email = fb.control('', [Validators.required, Validators.pattern(/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/), SignupComponent.alreadyExist()]);
this.username = fb.control('', [Validators.required, Validators.pattern(/^([A-ZÀ-ÿa-z0-9]{2,})+(?:[ _-][A-ZÀ-ÿa-z0-9]+)*$/)]);

this.userRegisterForm = fb.group({
    email: this.email,
    username: this.username
});

Custom alreadyExist() validator :

static alreadyExist(alreadyExist: boolean = false): any {

    return (control: FormControl): { [s: string]: boolean } => {

        if(alreadyExist) {
            return { emailAlreadyExist: true }
        }
    }
}

onSubmit() :

this.user.create(newUser)
    .subscribe(
        data => {
            this.router.navigate(['signin']);
        },
        error => {
            if(error.status === 401) {

                // CALL THE VALIDATOR HERE TO SET : FALSE
                SignupComponent.alreadyExist(true);
            }

            this.loading = false;
        });

It appear that the validator is called but the returned anonymous method inside it is never called... Maybe isn't a good practice, anyone can highlight me ? thx

like image 631
Kévin Vilela Pinto Avatar asked Aug 09 '26 14:08

Kévin Vilela Pinto


1 Answers

Ok I found a good solution.

In my case, for the email FormControl, I don't need a custom validator (even if is possible with setValidators()).

I can delete alreadyExist() and remove its declaration from the list of validators.

Then, I use setErrors() method available on FormControl :

onSubmit() :

this.user.create(newUser)
    .subscribe(
        data => {
            this.router.navigate(['signin']);
        },
        error => {
            if(error.status === 401) {

                // CALL THE VALIDATOR HERE TO SET : FALSE
                this.userRegisterForm.controls['email'].setErrors({
                  "emailAlreadyExist": true
                });
            }

            this.loading = false;
        });

The email FormControl has a new error, so, by this way i can attach a error message for this error.

like image 190
Kévin Vilela Pinto Avatar answered Aug 12 '26 08:08

Kévin Vilela Pinto



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!