以角反应形式提交表格后显示错误 [英] Showing error after form submit in angular reactive form

查看:72
本文介绍了以角反应形式提交表格后显示错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个反应形式,并使用了角材料的形式控制.

I have created a reactive form and using angular-material form control.

在表单提交时,我正在调用API,并且该API返回错误,因为其中的formControl值无效

On form submit I am calling API and that API is returning error because one of the formControl value is invalid

例如网站已注册.

现在,我想在中显示此错误消息,但该错误未显示.

Now, I want to show this error msg in , But the error is not showing.

  <mat-form-field class="full-width website"
    [appearance]="matAppearance">
    <mat-label>Website URL</mat-label>
    <input matInput
      placeholder="Website URL"
      name="website"
      formControlName="website">
    <mat-error *ngIf="configurationForm.get('website').hasError('required')">
      <strong>(required)</strong>
    </mat-error>
    <mat-error *ngIf="configurationForm.get('website').hasError('pattern')">
      Invalid URL
    </mat-error>
    <mat-error *ngIf="websiteErrMsg">{{websiteErrMsg}}</mat-error>
  </mat-form-field>

  public submitForm() {
      this.testService.register().subscribe(
        sucRes => {
          console.log('done);
        },
        errRes => {
          if (errRes.error === 'Website is already registered') {
              this.websiteErrMsg = 'Website Already Registered!';
          }
        }
      );
  }

问题1 :我在做什么错误?

我尝试更改 mat-error div ,然后可以正常工作.现在想知道为什么它不适用于 mat-error

I have tried changing mat-error or div, then is working. Now wanted to know why it is not working with mat-error

推荐答案

虽然不完全正确,但我认为使用异步验证器(请参见

It's not exact, but I think taht using an async validator (see the docs) you can resolve your problem. The problem with asyncValidatros are is the perfomance. If you not use updateOn 'blur' or 'submit' Angular makes a call each time you change the form.

想象一下,您有一个返回可观察的true或false的服务,如

Imagine you has a service that return an observable of true or false like

@Injectable({ providedIn: 'root' })
export class ApiService {
  getWebName(webName: string): Observable<boolean> {
    const isTaken = webName=="Vivek Kumar";
    return of(isTaken).pipe(delay(1000));
  }
}

您需要使用FormGroup和FormControl的构造函数创建formGroup,以指示何时进行评估.无法使用FormBuilder

You need create the formGroup using the constructor of FormGroup and FormControl to indicate when you make the valitation. It's not possible using FormBuilder

this.testForm = new FormGroup(
  {
    name: new FormControl("Vivek Kumar", {
      asyncValidators: this.checkIfNotRegister(),
      validators: Validators.required, 
      updateOn: 'blur'
    }),
    age: new FormControl(30, {
       validators:Validators.required,
       updateOn: 'blur'
    })
  }
);

我们的函数"checkIfNotRegister"是

Our function "checkIfNotRegister" is

checkIfNotRegister(): AsyncValidatorFn {
    return (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
      return this.service.getWebName(control.value).pipe(
        map(res => res ? { repeat: "name yet register" } : null)
      )
    };
  }

.html就像

<form [formGroup]="testForm">
    <mat-form-field class="name" appearance="outline">
        <input matInput placeholder="Name" formControlName="name">
    <mat-error *ngIf="testForm.get('name').hasError('required')">
      Name is required*
    </mat-error>
    <mat-error *ngIf="testForm.get('name').hasError('repeat')">
      Unknown server Error
    </mat-error>
    <mat-hint *ngIf="testForm.get('name').pending">Validating...</mat-hint>
  </mat-form-field>

  <mat-form-field class="age" appearance="outline">
        <input matInput placeholder="Age" formControlName="age">
    <mat-error *ngIf="testForm.get('age').hasError('required')">
      Age is required*
    </mat-error>
  </mat-form-field>

  <div>
    <button type="submit" (click)="submitForm()">Submit</button>
  </div>
</form>

看看我们如何使用< mat-h​​int> 来显示何时检查可观察对象

See how we use <mat-hint> to show when is checking the observable

更新仅检查Submit()中的异步验证器

Update only check the async validators in submit()

如果我们提交以下内容:

If we make in submit some like:

  submitForm() {
    if (this.testForm.valid)
    {
      //Add an async validators
      this.testForm.get('name').setAsyncValidators(this.checkIfNotRegister());
      //force Angular to updateValueAndValidity
      this.testForm.get('name').updateValueAndValidity();
      //remove the async validator
      this.testForm.get('name').setAsyncValidators(null);
    }
  }

更新2019-06-27

但是这不要等到检查是否有效,因此需要再做一步,以至于怀疑this.testForm.statusChanges,所以我们的SubmitForm变得像

But this don't wait to check if is valid, so need make another step that it's susbcribe to this.testForm.statusChanges, so our submitForm becomes like

submitForm() {
    if (this.testForm.valid) {
      this.testForm.statusChanges.pipe(take(2),last()).subscribe(res=>{
          //if res=='VALID' make something
          //if res=='INVALID'we don't need make nothing
          console.log(res)
      })
      this.testForm.get('name').setAsyncValidators(this.checkIfNotRegister());
      this.testForm.get('name').updateValueAndValidity({onlySelf:false,emitEvent:true});
      this.testForm.get('name').setAsyncValidators(null);
    }

我们的表单不需要验证器onBlur或onSubmit

Our form not need validator onBlur or onSubmit

this.testForm = new FormGroup(
      {
        name: new FormControl("Vivek Kumar", Validators.required),
        age: new FormControl(30, Validators.required)
      }
    );

您可以在 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆