Angular ReactiveForm Error Handling Through Switch Case

五迷三道 提交于 2019-12-24 10:51:11

问题


I have a reactive form in which I validate the different fields with ngif.

For example:

  <mat-form-field>
  <input  matInput formControlName="name" placeholder="Name">
  <mat-error 
  *ngIf="personForm.get('name').hasError('required')">Name is 
   empty</materror>
  <mat-error *ngIf="personForm.get('name').hasError('minlength')">Needs more 
   than 3 characters</mat-error>
  </mat-form-field>

Would it be possible to do the same thing in a switch case statement and how would one go on about doing this?

I imagened something like this

validateErrors {
  switch(errorHandling) {
  case 1: 'Name is empty';
  case 2: 'Needs more than 3 characters';
  }
}

How can I get the mat-errors to display these different cases? Any guidance would be much appreciated, thank you!


回答1:


I recommend another way to handle validation errors in reactive forms.

Look at working example on stackblitz.

Here is an example for that:

Step 1: Create class ErrorMessage

This class is an model for ErrorMessage, which you will use in form template.

export class ErrorMessage {
  constructor(
    public forControl: string,
    public forValidator: string,
    public text: string
  ) { }
}

Step 2: Create your FormGroup

  myForm: FormGroup;

  constructor(private fb: FormBuilder) { }

  ngOnInit() {
    this.createForm();
  }

  createForm() {
    this.myForm = this.fb.group({
      name: [null, [Validators.required, Validators.maxLength(255)]],
      email: [null, [Validators.required, Validators.email, Validators.maxLength(255)]],
      password: [null, [Validators.required, Validators.minLength(12)]]
    });
  }

Step 3: Create const with error messages for your form

Create for each form field validator an error message. Here is example for an form with three fields: name, email, password.

import { ErrorMessage } from './error-message';

export const MyFormErrorMessage = [
  new ErrorMessage('name', 'required', 'Name is required'),
  new ErrorMessage('name', 'maxlength', 'Name should have maximal 255 chars'),
  new ErrorMessage('email', 'required', 'Email is required'),
  new ErrorMessage('email', 'email', 'Email is not valid'),
  new ErrorMessage('email', 'maxlength', 'Email should have maximal 255 chars'),
  new ErrorMessage('password', 'required', 'Password is required'),
  new ErrorMessage('password', 'minlength', 'Password should have minimal 12 chars')
];

Step 4: Create variable for errors in your component.ts

  myForm: FormGroup;

  errors: { [key: string]: string } = {};

  constructor(private fb: FormBuilder) { }

Step 5: Function for error handling by form status changes

In this function you iterate MyFormErrorMessage and get control for each form field. After that check if control valid or invalid and add the error message to errors variable.

  updateErrorMessages() {
    this.errors = {};
    for (const message of MyFormErrorMessage) {
      const control = this.myForm.get(message.forControl);
      if (control &&
          control.dirty &&
          control.invalid &&
          control.errors[message.forValidator] &&
          !this.errors[message.forControl]) {
        this.errors[message.forControl] = message.text;
      }
    }
  }

Step 6: Subscribe to myForm statusChanges and run updateErrorMessages function

Add this:

this.myForm.statusChanges.subscribe(() => this.updateErrorMessages());

to createForm():

  createForm() {
    this.myForm = this.fb.group({
      name: [null, [Validators.required, Validators.maxLength(255)]],
      email: [null, [Validators.required, Validators.email, Validators.maxLength(255)]],
      password: [null, [Validators.required, Validators.minLength(12)]]
    });
    this.myForm.statusChanges.subscribe(() => this.updateErrorMessages());
  }

Step 7: Modify your form template

Now you can use errors vairable in template to output error messages:

<form [formGroup]="myForm" (onSubmit)="submitForm()">
  <div class="form-group" 
       [class.has-error]="errors.name"
       [class.has-success]="!errors.name && myForm.controls['name'].value">
    <label for="name">Name</label>
    <input type="text" id="name" formControlName="name" required>
    <span class="help-text" *ngIf="errors.name">{{ errors.name }}</span>
  </div>
  <div class="form-group" 
       [class.has-error]="errors.email"
       [class.has-success]="!errors.email && myForm.controls['email'].value">
    <label for="email">Email</label>
    <input type="text" id="email" formControlName="email" required>
    <span class="help-text" *ngIf="errors.email">{{ errors.email }}</span>
  </div>
  <div class="form-group" 
       [class.has-error]="errors.password"
       [class.has-success]="!errors.password && myForm.controls['password'].value">
    <label for="password">Password</label>
    <input type="password" id="password" formControlName="password" required>
    <span class="help-text" *ngIf="errors.password">{{ errors.password }}</span>
  </div>
</form>

In my projects I use this way to handle errors from validators. This way also works fine with custom validators.

Pros of this solution:

  • Easy
  • Ready for error translation
  • Works with custom validators


来源:https://stackoverflow.com/questions/48658368/angular-reactiveform-error-handling-through-switch-case

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!