Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Http doesn't work in Angular 2 custom asynchronous validation

I'm trying to create a custom asynchronous validator, that goes to the server and checks if an email is already registered.

Unfortunately, it seems that the get request is never fired, because nothing happens. I've tried multiple console.logs inside subscribe, but they didn't run.

I've checked if that request works outside of the validator, and it does, so that's not the problem.

import { Component } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
import { Response, Http } from '@angular/http';

 @Component({
     templateUrl: 'build/pages/welcome/signup/signup.html',
     providers: [AuthService, CustomValidators]
})
export class Signup {

     signupForm: FormGroup;

     constructor(private formBuilder: FormBuilder, private http: Http) {

         this.signupForm = formBuilder.group({
             'email': ['', Validators.required, this.checkEmail],
         }):
     }

     checkEmail(control: FormControl): Promise<any> {

          const promise = new Promise<any>(
             (resolve, reject) => {

                 this.http.get('/sharealead/main.php?action=checkEmail').subscribe(
                     (res: Response) => {
                         console.log('it never gets here');
                         console.log(res)
                         if (res.text() == 'already there') {
                             resolve({'emailTaken': true});
                         } else {
                             resolve(null);
                         }
                     },
                     (err) => {
                         console.log('it never gets here');
                         console.log(err);
                    }
                 )   
             }
         );
         return promise;
     }

}
like image 433
Alexandru Pufan Avatar asked Aug 11 '16 15:08

Alexandru Pufan


People also ask

What are the synchronous validators that angular provides?

The second argument is for any synchronous validators that we want to use and these can either be ones that Angular provides, or they can be custom ones we create ourselves. The validators that Angular provides are: The validator that we've set up on the Control for password looks a bit different.

What is async validator directive in ngmodel?

Async validator directive is used with ngModel in template-driven from. Async validator is used to validate data against the data located at remote server. To avoid frequent hit to server we should also use synchronous (sync) validators such as required, email, minlength and maxlength etc.

How to use asyncvalidatorfn in formcontrol in angular?

Angular provides AsyncValidatorFn interface to create custom async validator function that will be used by FormControl in reactive form. Find the structure of AsyncValidatorFn interface from Angular doc. AsyncValidatorFn has a method declaration that has argument as AbstractControl and it will contain latest value of the form control.

How do you implement asynchronous validation?

certain validators can need to perform an asynchronous operation, like calling a backend or a promise-based library. This can be implemented by having the validator return either a promise or an observable For validation to work properly, it's usually necessary to fine-tune exactly when the validators of a field are triggered.


1 Answers

It's because you reference the function and you lose the this context. You can use the bind method or a wrapping arrow function to fix that (link the function to the component instance):

this.signupForm = formBuilder.group({
         'email': ['', Validators.required, this.checkEmail.bind(this) ],
});

or

this.signupForm = formBuilder.group({
         'email': ['', Validators.required, (control:Control) => {
           return this.checkEmail(control);
         } ],
});

In your case, this doesn't contain an http property...

like image 72
Thierry Templier Avatar answered Sep 20 '22 01:09

Thierry Templier