带有角度反应形式的异步形式验证

时间:2019-09-16 21:09:27

标签: angular typescript angular-reactive-forms angular-validation

我有一个问题,我没有用角度的反应形式进行异步验证。在编写有关输入的内容时,我可以保持查询处于活动状态,它为我带来了结果,但无法在html中发送错误。我是新手,我不知道代码中会缺少什么。

Component.ts

  this.registroForm = this.fb.group({
  nombre: ["", [Validators.required, Validators.pattern("[a-zA-Z ]*")]],
  apellido: ["", [Validators.required, Validators.pattern("[a-zA-Z ]*")]],
  username: [
    "",
    [Validators.required, this.validateEmailNotTaken.bind(this)]
  ],
  email: ["", [Validators.required, Validators.pattern(this.emailPattern)]],
  telefono1: [
    "",
    [
      Validators.required,
      Validators.maxLength(10),
      Validators.minLength(10),
      Validators.pattern("[0-9]*")
    ]
  ],
  condiciones: ["", [Validators.required]]
});

我的验证功能:每次我在输入中输入内容时,服务器都会通过以下方式对我进行响应:当名称存在于BD中时,它将带给我一个json数组中的数据,但是一个空数组这就是为什么data.length的原因。因此,如果等于1,则应显示错误。但是输入会写入任何内容,并且将其放置为红色,而不会显示特定的错误(用于验证材料角度),并且不显示其是否存在或名称不可用的错误。

  validateEmailNotTaken(control: AbstractControl) {
let username = {
  user: control.value
};
return this.authService.buscarUserUsername(username).subscribe(
  (data: any) => {
    console.log(data.length);
    if (data.length === 1) {
      return { userNameExists: true };
    }
  },
  err => {
    console.log(err);
  }
);

HTML

<mat-form-field appearance="outline" color="accent">
           <mat-label>Usuario</mat-label>
           <input formControlName="username" matInput placeholder="Nombre de usuario">
           <mat-error *ngIf="registroForm.controls['username'].errors?.required">Este campo es obligatorio
           </mat-error>
           <mat-error *ngIf="registroForm.controls['username'].errors?.pattern">No es un nombre de usuario valido
           </mat-error>
           <mat-error *ngIf="registroForm.get('username').errors?.userNameExists">
             Nombre de usuario no disponible               </mat-error>

         </mat-form-field>

1 个答案:

答案 0 :(得分:1)

问题是您正在尝试从subscribe()内部返回值。相反,您应该返回一个Observable<ValidationErrors | null>并带有此异步验证程序的映射响应。这可以通过使用诸如mapcatchError之类的管道运算符来实现:

validateEmailNotTaken(control: AbstractControl) {
  let username = {
    user: control.value
  };

  return this.authService.buscarUserUsername(username).pipe(
    map(data => {
      if (data.length === 1) {
        // return error
        return {
          userNameExists: true
        };
      }

      // return null for no errors
      return null;
    }),
    catchError(err => {
      // handle error
      console.log(err);
    })
  )
}

作为一般规则,请仔细检查Angular类/接口的返回类型。在返回类型为Observable<T>的任何地方,您可能无法使用subscribe(),而需要使用可管道运算符。

还如注释中所建议,请确保将验证器的属性传递给表单配置:

username: ["", Validators.required, this.validateEmailNotTaken.bind(this)]

希望有帮助!