1

I have a form in my angular app for login. I am trying to display form validation erros, but they won't show unless I place them outside <mat-form-field>.

I've tried adding an ErrorStateMatcher as explained here, but it won't work. I have copy pasted the same form structure that works for me in other components of the application. Here it is:

<form [formGroup]="loginForm" #formDir="ngForm">
    <mat-form-field>
        <input [errorStateMatcher]="matcher" autocomplete="off" matInput placeholder="Email"
            formControlName="username" name="username">
        <mat-icon matSuffix>alternate_email</mat-icon>
        <mat-error *ngIf="loginForm.controls['username'].hasError('required')">
            * This field is required
        </mat-error>
    </mat-form-field>

    <mat-form-field>
        <input [errorStateMatcher]="matcher" autocomplete="off" matInput placeholder="Password"
            formControlName="password" type="password" name="password" autocomplete>
        <mat-icon matSuffix>vpn_key</mat-icon>
        <mat-error *ngIf="loginForm.controls['password'].hasError('required')">
            * this field is required
        </mat-error>
    </mat-form-field>
</form>

Here it is my form instance:

constructor(private router: Router,
    private fb: FormBuilder) {
    this.loginForm = fb.group({
      username: new FormControl('', [Validators.required, Validators.email]),
      password: new FormControl('', [Validators.required])

    })
  }

Although the error messages are not displaying, the fields turn red when they are not valid (both Validators.required and Validators.email seem to be working).

I've also tried forcing the inputs to have errors on submit, only for testing purposes as I don't think it is a proper solution, like this:

    this.loginForm.controls['username'].setErrors({
      required: true
    })
    this.loginForm.controls['password'].setErrors({
      required: true
    })
    this.loginForm.markAllAsTouched();
    this.loginForm.controls['username'].markAsTouched();
    this.loginForm.controls['password'].markAsTouched();

These are the modules that I imported on app.module:

import { FormsModule, ReactiveFormsModule } from '@angular/forms';

What am I missing?

Macarena
  • 123
  • 8
  • https://stackoverflow.com/questions/58299931/angular-2-why-doesnt-material-want-to-show-error-message/58300325#58300325 – Eliseo Oct 09 '19 at 09:04
  • @Eliseo I am not using a custom validator, just Validators.required and Validators.email – Macarena Oct 09 '19 at 09:08
  • sorry, I confused your question with another. try using "get": `*ngIf="loginForm.get('password')?.hasError('required')"`: NOTE if only has an error, you can remove the *ngIf – Eliseo Oct 09 '19 at 09:55
  • @Eliseo thanks for the suggestion, but it is not working either. I use *ngIf for testing purposes, initially I was not using it. – Macarena Oct 09 '19 at 10:02
  • remove `#formDir="ngForm"` and `[errorStateMatcher]="matcher"`. By defect, the errors are showed when has error and are touched. At first you can maskAllasTouched if you want show it always – Eliseo Oct 09 '19 at 10:06
  • @Eliseo I use ngForm to subscribe submission and show/hide messages based on that. Also, I already tried markAllAsTouched as you can see in my above example . – Macarena Oct 09 '19 at 12:42

0 Answers0