I try to display an error message and error icon when matInput
has an error (controlled by a formControl
).
But if the form is submited without touch the field, error is not displayed.
View code playground on stackblitz
Or here is my code:
app.component.ts
ngOnInit() {
this.formGroup = new FormGroup({
email: new FormControl(null, [Validators.required, Validators.email]),
});
}
get emailHasError() {
return (
!this.formGroup.get('email').valid && this.formGroup.get('email').touched
);
}
app.component.html
<form [formGroup]="formGroup" class="form">
<mat-form-field class="form-element">
<input matInput placeholder="Email address" formControlName="email" />
<mat-error *ngIf="emailHasError">
{{ errorEmail }}
</mat-error>
</mat-form-field>
<div class="form-element">
<button mat-raised-button color="primary" type="submit" class="button">
Submit Form
</button>
</div>
</form>
However, the matInput
field turns red and seems to receive the error.
I read some solution that suggests to toggle a property isSubmit
on form submit. But seems to be ugly and and this requires passing this property to the child component if the form is split into several components.
How does Angular Material manage to detect if the form is submitted in order to display the error?
EDIT:
The only solution I found for now is to check classList
with @ViewChild
as follow. But it still seems to be a hacky way...
On stackblitz
I process as follow:
@ViewChild('matInput') matInput: ElementRef;
get hasError() {
return this.matInput?.nativeElement?.classList?.contains('ng-invalid');
}
<input
matInput
#matInput
placeholder="Email address"
formControlName="email"
/>
A custom ErrorStateMatcher may be a neat solution for this problem.
The ErrorStateMatcher controls exactly which set of conditions should display an error response in the UI. In the current example, it will display whenever isSubmitted is true, even if the form control is not "dirty" or "touched".
Here's a stackblitz demo.