I am following a tutorial in order to perform Asynchronous validation in Angular.
What I am trying to achieve is my custom validator which is shouldBeUnique should  be call after delay of 2 seconds. I am using setTimeout function in it but it is not working. even Error message not shows in div.
Here is my custom validation error file.
import { AbstractControl, ValidationErrors } from '@angular/forms';
export class UsernameValidator {
   static cannotContainSpace(control: AbstractControl): ValidationErrors | null {
        if ((control.value as string).indexOf(' ') >= 0 ) {
            return { cannotContainSpace: true };
        }
        return null;
    }
    static shouldBeUnique(control: AbstractControl): Promise<ValidationErrors | null> {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if (control.value === 'bilal') {
                    resolve({shouldBeUnique: true});
                } else {
                    resolve(null);
                }
            }, 2000);
        });
    }
}
HTML file.
<form [formGroup] = "form">
    <div class="form-group">
        <label for="username">Username</label>
        <input 
            formControlName = "username"
            id="username" 
            type="text" 
            class="form-control">
        <div *ngIf="username.touched && username.invalid" class="alert alert-danger">
            <div *ngIf="username.errors.required">username is required</div>
            <div *ngIf="username.errors.minlength">
                minlength {{username.errors.minlength.requiredLength}} is required
            </div>
            <div *ngIf="username.errors.cannotContainSpace">
                cannot contain space
            </div>
            <div *ngIf="username.errors.shouldBeUnique">
                    username should b unique
                </div>
        </div>    
    </div>
    <div class="form-group">
        <label for="password">Password</label>
        <input 
            formControlName = "password"
            id="password" 
            type="text" 
            class="form-control">
    </div>
    <button class="btn btn-primary" type="submit">Sign Up</button>
</form>
Type script file
import { Component } from '@angular/core';
import {FormGroup, FormControl, Validators} from '@angular/forms';
import { UsernameValidator } from './username.validator';
@Component({
  // tslint:disable-next-line:component-selector
  selector: 'signup-form',
  templateUrl: './signup-form.component.html',
  styleUrls: ['./signup-form.component.css']
})
export class SignupFormComponent {
  form = new FormGroup({
    username: new FormControl('', [
      Validators.required,
      Validators.minLength(3),
      UsernameValidator.cannotContainSpace,
      UsernameValidator.shouldBeUnique
    ]),
    password: new FormControl('' , Validators.required)
  });
  get username() {
    return this.form.get('username');
  }
}
                Async validators should be the third argument to FormControl, so you should initialize yours like this:
form = new FormGroup({
    username: new FormControl('', 
    [
      // regular validators
      Validators.required,
      Validators.minLength(3),
      UsernameValidator.cannotContainSpace
    ], 
    [
      // async validators
      UsernameValidator.shouldBeUnique
    ]),
    password: new FormControl('' , Validators.required)
  });
                        Async validators should be placed after validators,
export declare class FormControl extends AbstractControl {
  constructor(
    formState?: any,
    validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, 
    asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null
);
new FormGroup({
    username: new FormControl('', 
    [
      Validators.required,
      Validators.minLength(3),
      UsernameValidator.shouldBeUnique
    ], 
    [
     UsernameValidator.cannotContainSpace,
    ])
  });
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With