How to trigger event when form has been made dirty by user?

Viewed 39

My angular application have only check box and radio button. I want to trigger event when any of the field has been made dirty by user. currently the below if condition called even value has been changed by program itself. I used touched and pristine attribute but it always giving me false

this.myForm.valueChanges.subscribe(data => {
      if (this.myForm.dirty) {
        console.log('form is dirty');
      
      }
    });
3 Answers

tried with below option and it worked. emitEvent false will change the form value and also don't trigger the dirty event automatically.

    this.myForm.reset({},{
      emitEvent: false,
    });

Try using distinctUntilChanged as so.

this.myForm.valueChanges.pipe(distinctUntilChanged((a, b) => JSON.stringify(a) === 
                                                           JSON.stringify(b)))

                      .subscribe(changes => { console.log('The form changed!'); });

The JSON stringify is required as by default it only does a reference comparison. This way the code will only fire if the new value is different than the original.

Reference SO post: FormControl.detectchanges - why use distinctUntilChanged?

Here is a stackblitz that shows that this fires only on changes to form control, which validates that this is an acceptable solution: https://stackblitz.com/edit/angular-zena7t?file=src/app/app.component.html

You can tap into the changes variable to see exactly what changed. This way you can also have different behaviors set up if different inputs are changed. Though if for whatever reason you do want to trigger a change from the code and not have it cause a emitting of values then do it as MGX has shown in their answer, though at that point I would ask why are you overriding its default behavior of emitting a value change?

If you wish to be able to ignore the application changing the value programmatically, you can pass in a parameter when you set the value of the control.

Here is an example

  control = new FormControl('');

  constructor() {
    this.control.valueChanges.subscribe(() => console.log('Control has changed value'));
  }

  updateValue() {
    this.control.setValue(Math.random().toString(36).slice(2), { emitEvent: false });
  }

Related