0

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 Answers3

0

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,
    });
-1

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?

Spevacus
  • 584
  • 2
  • 13
  • 23
SomeStudent
  • 2,856
  • 1
  • 22
  • 36
  • 1
    This is not the right solution. – MGX Sep 22 '22 at 13:58
  • Except it is and fires on form value change, stackblitz: https://stackblitz.com/edit/angular-zena7t?file=src/app/app.component.html – SomeStudent Sep 22 '22 at 14:13
  • 1
    It works for YOUR implementation. Use objects as values, in which the keys order is not guaranteed, and it does not work anymore [like this](https://stackblitz.com/edit/angular-2tqm56?file=src%2Fapp%2Fapp.component.html,src%2Fapp%2Fapp.component.ts). Using JSON for comparison is everything but stable. As said, this is NOT the right solution. It might be ONE, but it is not the RIGHT one. – MGX Sep 22 '22 at 14:22
  • 1
    And finally, it's not "overriding the default behavior", it's thought to work like that. This is why the fonction `setValue` accepts a second parameter. – MGX Sep 22 '22 at 14:24
-1

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 });
  }

MGX
  • 2,534
  • 2
  • 14