Search code examples
angularangular6angular-forms

Aysnc validator angular 6


I am tryin to check username availablity on typing username using a rest api. I am using angular forms for validators. From backend I get true is username exists and false if not. I am using below code :

this.registerForm = this.formBuilder.group({
            userName: ['', [Validators.required, this.userNameValidator.bind(this)]],
        });

userNameValidator(control: AbstractControl) {
    setTimeout(() => {
        return this.adminService.checkUserName(control.value).subscribe((Response:any)=>{
            return Response._body ? true : {'invalidUserName': true};
        })
    }, 1000);}

Its showing null in errors property of form control


Solution

  • There are several things wrong with your code.

    1. You never actually return anything from the userNameValidator method, you should return an observable (or promise).
    2. You should not use setTimeOut, instead use timer from the RxJs library as this returns an observable.
    3. Use switchMap on the timer result to return your observable from your async call
    4. You should return a result using map and not subscribe, the controls validation will subscribe to the returned observable.
    5. If validation passes you should return null
    import { ValidationErrors } from '@angular/forms';
    import { Observable, timer } from 'rxjs';
    import { map, switchMap } from 'rxjs/operators';
    
    userNameValidator(control: AbstractControl): Observable<ValidationErrors | null> {
        return timer(1000).pipe(switchMap(() => {
            return this.adminService.checkUserName(control.value).pipe(map((Response:any)=>{
                return Response._body ? null : {'invalidUserName': true};
            }));
        }));
    }