Howard Ho
Howard Ho

Reputation: 51

How to implement Custom Async Validator in Angular4

I'm applying Angular 4 in my project and I am having trouble with Custom Validation using HTTP request.

I also tried this: How to implement Custom Async Validator in Angular2.

But it doesn't work in my project.

Here's what I've done so far:

Validation biding:

    userName: ['', [Validators.required, Validators.minLength(3), this.validateUserName.bind(this)]]

Value changes event:

    let userNameControl = this.individualForm.get('userName');
userNameControl.valueChanges.subscribe(value => {
    this.setErrorMessagesForUserNameControl(userNameControl)
  }
);

Validation function:

validateUserName(control: FormControl): Promise<any> {
let promise = new Promise<any>(
  (resolve, reject) => {
    if (this.oldUserNameForCheck != undefined) {
      this._individualUpdateService.isUserNameExisting(this.oldUserNameForCheck, control.value).subscribe(
        (res) => {
          if (res.isUserNameExisting) {
            console.log("existing");
            resolve({'existing': true});
          } else {
            console.log("NOT existing");
            resolve(null);
          }
        },
        (error) => {
          console.log(error);
        }
      );
    } else {
      resolve(null);
    }
  }
);
return promise;
}

Error Messages

I just try to validate the username by sending it to the back-end.

Here's the logs

As you can see, there's a message for "required", "minlength". Those work fine. But the message for Custom validation is not quite clear.

Upvotes: 4

Views: 1452

Answers (1)

Vitalii Ivanov
Vitalii Ivanov

Reputation: 3250

Async validator should be in the next parameter

userName: ['', 
    [ Validators.required, Validators.minLength(3) ], 
    [ this.validateUserName.bind(this) ] 
]

Also its better to have a factory method with required dependencies that would create validator, instead of using 'bind(this)'

userNameValidator(originalUsername, individualUpdateService) {
    return (control: FormControl): Promise<any> => {
        return new Promise<any>((resolve, reject) => {
            if (originalUsername != undefined) {
                individualUpdateService.isUserNameExisting(originalUsername, control.value).subscribe(
                    (res) => {
                        if (res.isUserNameExisting) {
                            console.log("existing");
                            resolve({ 'existing': true });
                        } else {
                            console.log("NOT existing");
                            resolve(null);
                        }
                    },
                    (error) => {
                        console.log(error);
                    }
                );
            } else {
                resolve(null);
            }
        })
    }
}

userName: ['', 
    [ Validators.required, Validators.minLength(3) ], 
    [ this.userNameValidator(this.oldUserNameForCheck, this._individualUpdateService) ] 
]

Upvotes: 2

Related Questions