angularangular-materialangular2-form-validation

Angular 7 + Angular Material => Form Validation Error not appearing until leaves focus


<form (ngSubmit)="saveChanges()">
    <mat-form-field appearance="outline" >
      <mat-label>New ID</mat-label>
      <input required matInput name="newName" [style]="elemStyles" [formControl]="email">
      <mat-error *ngIf="email.invalid && (email.dirty || email.touched)">
        <p class="error-message" *ngIf="email.errors.duplicateId">ID <strong>already</strong> exists.</p>
        <p class="error-message" *ngIf="email.errors.required">This field is <strong>required.</strong></p>
      </mat-error>
    </mat-form-field>
    <div class="action-buttons">
      <button type="submit" [disabled]="email.invalid" mat-mini-fab class="accept action-button">
        <mat-icon fontSet="fontawesome" fontIcon="fa-check" class="fa-xs action"></mat-icon>
      </button>
      <button type="submit" mat-mini-fab class="cancel action-button">
        <mat-icon fontSet="fontawesome" fontIcon="fa-times" class="fa-xs action"></mat-icon>
      </button>
    </div>
  </form>

The mat-error part is only showing AFTER leaving the focus of the input field. The Accept Button gets disabled tho. Any info how to fix this behaviour to get the error message while the user types?

I tried removing (email.dirty || email.touched) too, but it's not working :/

My Custom Validator:

export class DuplicateIDValidator {
  static duplicateIDValidator(pageStructure: PageStructureService) {
    return (control: AbstractControl): {[key: string]: any} | null => {
      return pageStructure.pages.every(page => page.questionId !== control.value.toLowerCase()
        || page.questionId === pageStructure.selectedPages[0].questionId) ? null : {duplicateId: true};
    };
  }
}

Solution

  • The solution was an ErrorStateMatcher.