Angular Material - show mat-error on button click

Since you want to show mat error on button's click, please try the below: For Angular6 version:

  1. Import the required classes
import { FormControl, FormBuilder, FormGroup } from '@angular/forms';
  1. Declare form control in your component.ts file:
nameControl = new FormControl('');
  1. Add the control in html:
<mat-form-field  style="width: 100%" floatPlaceholder="never">
    <input matInput placeholder="your placeholder text" [formControl]="nameControl" required/>
    <mat-error *ngIf="nameControl.errors?.required">name is required</mat-error>
</mat-form-field>
  1. Add this to your button click event handler:
this.nameControl.markAsTouched();

It's important to check how you are using the form control, ".markAsTouched()" on point 4 will show the mat error for the corresponding form control.


See how to use a form with a custom ErrorStateMatcher

If you wish to override this behavior (e.g. to show the error as soon as the invalid control is dirty or when a parent form group is invalid), you can use the errorStateMatcher property of the matInput. The property takes an instance of an ErrorStateMatcher object. An ErrorStateMatcher must implement a single method isErrorState which takes the FormControl for this matInput as well as the parent form and returns a boolean indicating whether errors should be shown. (true indicating that they should be shown, and false indicating that they should not.)

I would make a separate file such as default.error-matcher.ts

/** Error when invalid control is dirty or touched*/
export class MyErrorStateMatcher implements ErrorStateMatcher {
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    return !!(control && control.invalid && (control.dirty || control.touched));
  }
}

Then in the TS file add:

matcher = new MyErrorStateMatcher();

Then change the input to use matcher:

<mat-form-field>
    <input matInput placeholder="Due Date" name="dueDate" [(ngModel)]="dueDate" [formControl]="dueDateValidator" [errorStateMatcher]="matcher" required>
    <mat-error *ngIf="dueDateValidator.invalid">Due Date is required for Tasks</mat-error>
</mat-form-field>

Angular 8 has a new forms method: markAllAsTouched();

This will mark a control/form and ALL DESCENDANTS as touched!!!

So:

this.form.markAllAsTouched();

Is the solution.