Set Form to Pristine without clearing data

AngularAngular Reactive-Forms

Angular Problem Overview


I have a form that displays a list of <input type="text"> elements. They all share a common save button which is disabled until the form becomes dirty. Then, once the user clicks the save button, the data will be submitted to the server. If the server successfully saved the data, I want to reset the form to a pristine state, but I want to keep all of the data in the form so the user can edit the data further if they so choose.

After searching, I have found the NgForm.reset() method. While this does set the form to pristine, it unfortunately also clears out the form. The reset method does seem to have a value parameter, but I can't seem to find out what it does. Nevertheless, I don't want the data cleared out.

I have also tried myForm.pristine = true as well, but this causes a reload of the page for some reason.

Here is a plunkr demonstrating the problem.

Angular Solutions


Solution 1 - Angular

What you're looking for is myForm.form.markAsPristine().

Solution 2 - Angular

At the moment I can suggest two possible solutions. First one is really close to what you've suggested, as form's reset method has following signature and accepts form value as a first argument:

//@angular/forms/src/model.d.ts:
reset(value?: any, {onlySelf}?: { onlySelf?: boolean; }): void;

In the submit handler, we will capture a copy of the last state:

const { myForm: { value: formValueSnap } } = this;

And do the reset itself:

this.myForm.reset(formValueSnap, false);

Another option from the times, when there was no possibility to reset form, is to create a helper method, which will mark each control as pristine and will keep the data. It can be called in the same submit helper in place of the resetting.

private _markFormPristine(form: FormGroup | NgForm): void {
    Object.keys(form.controls).forEach(control => {
        form.controls[control].markAsPristine();
    });
}

Link to the updated plunkr.

Solution 3 - Angular

If you happen to be using Template-Driven forms and you have something like this in your component: @ViewChild('myForm') myform: NgForm;

I've found that the markAsPristine() is a function on the form property of your form. So it would be this.myform.form.markAsPristine().

Just thought I'd add this in case others come across markAsPristine() as not being defined.

Solution 4 - Angular

When using Angular's reactive forms, you can use markAsPristine() on the FormGroup:

export class MyPage

  // Your form group
  public formGroup: FormGroup;

  ngOnInit() {
    this.formGroup = this.formBuilder.group({
      // Add your form controls here
    });
  }

  onSubmitForm() {
    // Get form value and save data on the server
    // ...
    
    this.formGroup.markAsPristine(); // <=== Mark form group as pristine
  }
}

See also: documentation for AbstractControl.markAsPristine(). Note: FormGroup is a subclass of AbstractControl. It will mark all children of the FormGroup as pristine.

Solution 5 - Angular

I think i solve done this on my method:

form.controls['contato'].reset();

Solution 6 - Angular

I haven't found a markAsPristine() in the form property, but I found a _pristine property, this.myForm['form']._pristine which can be set to true.

@ViewChild('myForm') myForm: ElementRef;
this.myForm['form']._pristine = true;

Solution 7 - Angular

To reset the form:

this.form.reset();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionspectacularbobView Question on Stackoverflow
Solution 1 - AngularMohamed FakhreddineView Answer on Stackoverflow
Solution 2 - AngularDaniel MylianView Answer on Stackoverflow
Solution 3 - AngularMikeView Answer on Stackoverflow
Solution 4 - AngularKlemens ZleptnigView Answer on Stackoverflow
Solution 5 - AngularDarshak ShekhdaView Answer on Stackoverflow
Solution 6 - AngularAndres SuarezView Answer on Stackoverflow
Solution 7 - AngularMattView Answer on Stackoverflow