I want to encapsulate the mat-error into its own component since the text tends to be quite long. Therefore I thought about:
<form [formGroup]="form">
<mat-form-field>
<input matInput formControlName="title" placeholder="Title" required />
<app-mat-error-too-long [ctrl]="form.controls.title"></app-mat-error-too-long>
</mat-form-field>
</form>
and
<mat-error *ngIf="ctrl.hasError('maxlength')">
<span >Input too long</span>
<span> </span>
<span>{{ctrl.getError('maxlength').actualLength}}/{{ctrl.getError('maxlength').requiredLength}}</span>
</mat-error>
with the component:
import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { AbstractControl } from '@angular/forms';
@Component({
selector: 'app-mat-error-too-long',
templateUrl: './mat-error-too-long.component.html',
styleUrls: ['./mat-error-too-long.component.scss'],
})
export class MatErrorTooLongComponent implements OnInit {
@Input() ctrl: AbstractControl
constructor() { }
ngOnInit(): void {
}
}
But if I do so the error is not displayed properly and is right under the component:

mat-error needs to be used directly inside mat-form-field to work correctly. So what you can do is to use an attribute selector instead for your child component and attach it to mat-error:
<mat-form-field>
<input matInput formControlName="title" placeholder="Title" required />
<mat-error app-mat-error-too-long [ctrl]="form.controls.title"></mat-error>
</mat-form-field>
Then you need to of course remove the mat-error tag from the child and instead just show your messages. The child selector also needs to change, wrap brackets around it:
selector: '[app-mat-error-too-long]'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With