Angular material: mat-error not showing despite true methods

I discovered asubtle situation where this can occur.

If you add a [formGroup] directive on something like a <div> then it will not get submitted == true when the form is submitted (it must be on a <form> for that to occur).

The form being submitted is one of two triggers for displaying the error - the other is for the field to have been touched. And touched means onBlur which means the focus must have been lost.

So you can get this situation:

  • You have [formGroup] on a div

  • You have something like a username / password form.

  • You also have a submit button.

  • You enter both fields and hit enter.

  • Your validation triggers an error but it doesn't show! WHY!

  • Because you never blur-ed the password field (take a look at your cursor - it's still in the password field isn't it!)

  • The easiest solution is to only ever add [formGroup] to a <form> tag

  • The other is to create a custom ErrorStateMatcher

If you are passing a formGroup to a 'dumb' child component via an @Input (that is to a dumb component that doesn't manage its own form) you can use dependency injection and pass in the FormGroupDirective instead in the constructor.


MatFormField only displays mat-error elements when the FormControl has an error. It does not display just because you tell it to via ngIfElse - that would only work subject to the form control state. One way to solve this problem is to create a custom validator and use it to check that the passwords match. You could also set an error on the field from your equalPasswords() function. That should be something like:

equalPasswords(): boolean {

    const matched: boolean = this.password1.value === this.password2.value;

    console.log('equaltest', matched);

    if (matched) {
        this.signupForm.controls.password2.setErrors(null);
    } else {
        this.signupForm.controls.password2.setErrors({
           notMatched: true
        });
    }

    return matched;
}