首页 > 解决方案 > Set custom validation error using subscribe

问题描述

I wan to set the validation error based on data present in the database.

Formcontrol with custom validator function:

nUname: ['', [Validators.required,unique_uname]]

Custom validator function:

Below function takes the username and using post request in service fetch the data. If the username is in database service return response with status as 'S' else error with status 'F'.

If the status is 'S' then the error 'uname_repeat' should be set to the formcontrol. uname_repeat error is not setting in subscribe, but outside subscribe it working as required.

function unique_uname(){
  return (control: AbstractControl): {[key: string]:any} | null => {
    const uname = control.value;
    if(uname.length!=0){
      ser.get_user(uname).subscribe(
        (res) => {
          if (res['status']=='S') {
             return {'uname_repeat':true} <-- This is not working
          }
        },
        (err) => {
          if (err['error']['status']=='F') {
            return null;
          }
        }

        );
        return {'uname_repeat':true} <-- This working

      }
      return null;
    };
  }

What modification are required to get the expected result.

标签: angularsubscriptionform-control

解决方案


您需要在这里使用的是async validator

有两种方法可以async validators以反应形式使用。

首先,您可以在组件中添加验证功能并将其包含在您的响应式表单中。

validateEmailNotTaken(control: AbstractControl) {
    return this.signupService.checkEmailNotTaken(control.value).pipe(
        map(res => {
            return res ? null : { emailTaken: true };
        })
    );
}

并包括以下形式:

this.myForm = this.fb.group({
    name: ['', Validators.required],
    email: [
        '',
        [Validators.required, Validators.email],
        this.validateEmailNotTaken.bind(this)
    ]
});

或者其次,您可以创建一个单独的验证文件

export class ValidateEmailNotTaken {
    static createValidator(signupService: SignupService) {
        return (control: AbstractControl) => {
            return signupService.checkEmailNotTaken(control.value).pipe(
                map(res => {
                    return res ? null : { emailTaken: true };
                })
            );
        };
    }
}

并包括以下形式:

this.myForm = this.fb.group({
    name: ['', Validators.required],
    email: [
        '',
        [Validators.required, Validators.email],
        ValidateEmailNotTaken.createValidator(this.signupService)
    ]
});

这是一个 stackblitz演示供参考。


推荐阅读