Reputation: 1398
I'm using angular material and reactive form. I want when errors messages are showing, only one message show and if I solve one error show another.
How it is now:
HTML:
<mat-form-field class="example-full-width">
<input matInput
placeholder="Username"
name="username"
[formControlName]="'username'">
<mat-error *ngIf="form.controls['username'].errors && form.controls['username'].touched">
<div *ngIf="form.controls['username'].errors.required">
Username is <strong>required</strong>
</div>
<div *ngIf="form.controls['username'].errors.minlength">
Required length: {{form.controls['username'].errors.minlength['requiredLength']}}
Actual length:{{form.controls['username'].errors.minlength['actualLength']}}
</div>
<div *ngIf="form.controls['username'].errors.pattern">
Only a-zA-Z0-9
</div>
</mat-error>
</mat-form-field>
Maybe I should use if else or something else? What do you think?
Upvotes: 8
Views: 13769
Reputation: 1798
Was having the same problem.
This is what I came up with, simple and elegant.
No simultaneous mat-error
's will be shown when there are two or more.
Yet, the whole form will be invalid, disabling the submission.
mat-error + mat-error {
display: none;
}
Upvotes: 7
Reputation: 3418
You are almost there. To display different error messages one at a time, just check the other errors if they exist.
<mat-error *ngIf="form.controls['username'].errors && form.controls['username'].touched">
<div *ngIf="form.controls['username'].errors.required &&
!form.controls['username'].errors.pattern
&& form.controls['username'].errors.minlength">
Username is <strong>required</strong> //this is the first message error
</div>
<div *ngIf="form.controls['username'].errors.minlength &&
!form.controls['username'].errors.required &&
!form.controls['username'].errors.pattern"> // display error if required and pattern errors don't exist Required length: {{form.controls['username'].errors.minlength['requiredLength']}}
Actual length:{{form.controls['username'].errors.minlength['actualLength']}}
</div>
<div *ngIf="form.controls['username'].errors.pattern &&
!form.controls['username'].errors.required &&
!form.controls['username'].errors.minlength
">
Only a-zA-Z0-9
</div>
</mat-error>
Basically just negate !
all the other error messages. This works for me.
Hope this helps.
Upvotes: -1
Reputation: 3443
You can have one <mat-error>
check if the control is invalid
and then get your appropriate error message i.e.:
<mat-error *ngIf="form.controls['username'].invalid">{{ getErrorMessage() }}</mat-error>
And then in your .ts
you would have a function to retrieve the appropriate error message:
getErrorMessage() {
return this.form.controls['username'].hasError('required') ? 'You must enter a value' :
this.form.controls['username'].hasError('pattern') ? 'Not a valid username' :
this.form.controls['username'].hasError('minlength') ? 'Required length is at least 3 characters' :
'';
}
You don't need those divs
, the <mat-error>
element should suffice if you have appropriate styles applied.
Here is a stackblitz example.
Upvotes: 17