Angular Reactive forms : how to reset form state and keep values after submit
Caution for users of @angular/components (material)
There's an added complication if you're using angular material controls, with mat-error
to display your errors. Such errors are displayed based on the result of an ErrorStateMatcher
(in addition to any *ngIf
you may have applied).
The default ErrorStateMatcher displays errors based on a boolean:
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean
{
return !!(control && control.invalid && (control.touched || (form && form.submitted)));
}
So what this means in English is:
If the form has ever been submitted and one if its controls becomes invalid (per validation rules) then the error will be displayed.
This is often not what you want (especially if you're reading this question!).
Looking at the source code - there isn't a way to set submitted = false
unless you call resetForm
on the ngForm directive (not the FormGroup object). Setting states as pristine or untouched don't reset submitted to false.
If you're using mat-error
you may find it easier to create your own ErrorStateMatcher (simple interface) for custom logic if this is an issue.
Note: ErrorStateMatcher is only in angular material - and not a part of standard angular forms.
The solution of @smnbbrv works pretty well.
You can also provide your actual form value to reset() method.
Given the fact myReactiveForm
is a Reactive form in your component. After successful submit of your form (by calling a service for example), then your can do:
this.myReactiveForm.reset(this.myReactiveForm.value);
It will reset the form and set the "new" form values to the same value you form had.
This method can be see within Tour of Hero example Official Angular.io doc
That's pretty much easy:
this.form.markAsPristine();
this.form.markAsUntouched();
This resets the form metadata and the form is pristine again
04-06-2020: Ionic 5+ and Angular 9+
Just a single line. i.e. this.form.reset();
Resets the FormGroup, marks all descendants are marked pristine and untouched, and the value of all descendants to null.
form: FormGroup;
constructor(private formBuilder: FormBuilder, ) { }
resetTheForm(): void {
this.form.reset();
}