I have an Angular Reactive form with a custom ErrorStateValidation. The desired behavior is this:
- Only show invalid error message when a field has been submitted and there is nothing entered in the text input field.
- If the form has been successfully submitted, reset validation and submit status to false and do not show the invalid error message.
I have #1 working with the custom ErrorStateMatcher. After successful submission, I'm calling the resetForm function on the FormGroupDirective which DOES reset the submit status to FALSE. The problem is, the form seems to be getting submitted twice so the submit status goes back automatically to TRUE and immediately shows the invalid message after successful submission.
Working example of this problem can be found here https://stackblitz.com/edit/add-angular-material-p9btep?devtoolsheight=33&file=src/app/app.component.ts
CodePudding user response:
This is because of bubbling of form submit event. Your form is being submitted twice:
- Manually by button click or
onKeyUp
with enter key - Submission by the browser automatically
I suggest you remove the manual submission with click/enter and add the (ngSubmit)
to your form and use browsers behaviour to your advantage instead as follows:
<h1>Angular Forms Example</h1>
<form
[formGroup]="empForm"
#empFormDirective="ngForm"
(ngSubmit)="onAddEmpTopic($event, empFormDirective)" <!-- add this -->
>
<mat-form-field appearance="standard">
<mat-label>Add a topic</mat-label>
<input
matInput
[errorStateMatcher]="customErrorStateMatcher"
placeholder="I wish to discuss..."
formControlName="empTopic"
/>
<mat-error *ngIf="empTopic.errors?.required"
>Topic must not be empty.</mat-error
>
</mat-form-field>
<button mat-button>
<mat-icon>note_add</mat-icon>
</button>
</form>
Working example: https://stackblitz.com/edit/add-angular-material-j1wjno?devtoolsheight=33&file=src/app/app.component.html
CodePudding user response:
Needs a delay to work.
The Issue is submit events are clashing with reset events, generally form would be submitted by an api async call where you will reset the form on a 200 response inside an observable and promise response.
console.log(' Call API to add a topic!');
// set timeout can represent subscription or promise response.
setTimeout(() => {
empFormDirective.resetForm(empFormDirective.value);
});