Search code examples
angularangular2-forms

Angular 2 Reactive Form - Display a reset button only if form is dirty


I have a reactive form and I want to display a reset button, that will reset the form values to initial.

Now, the button should only appear if form is dirty.

The form definition is:

this.form = new FormGroup({
  firstName: new FormControl(''),
  lastName: new FormControl('')
});

First approach that I've tried was by using form.dirty property of the Reactive form, but it is not what I need. The form.dirty returns true in the scenario when the user types something in inputs, then deletes it, and form controls have the same value as initial.

The second approach is to save the initial values: this.initialFormValue = this.form.value;, then implement a custom function that compares the current form value with the initial one:

isFormDirty(): boolean {
   return JSON.stringify(this.initialFormValue) !== JSON.stringify(this.form.value);
}

(the comparison is not very smart, maybe I will use some Lodash function, etc, but that's not the point of the question).

<div *ngIf="isFormDirty()" style="color: red;">Form is really dirty</div>

It works, but the function is called very very often (when Angular detects changes or something) and I think that I may have some performance problems.

I think that I might use valueChanges observable, and emit a new value...

Do you have any other suggestions?

Stackblitz: https://stackblitz.com/edit/angular-jywynt

Thanks.


Solution

  • Yes, you can listen to valueChanges Observable where you can control how often it should be executed, for example you can use debounceTime to reduce calls.

    this.form.valueChanges
     .pipe(debounceTime(50))
     .subscribe(newValue => {
       if (this.isFormDirty()) {
         this.form.markAsDirty();
       } else {
         this.form.markAsPristine();
       }
     });
    

    Now you can simply use the same property form.dirty from FormGroup object:

    <div *ngIf="form.dirty" style="color: red;">Form is really dirty</div>
    <div *ngIf="!form.dirty">Form is not dirty (values are identical to initial)</div>
    

    Forked Stackblitz