10

Im building a reactive forms using angular 6, this form contain 3 attributes (name,age,phone) and i would to get just the changed values not all form values.

this.refClientForm = this.formBuilder.group({
  name: [],
  phone: [],
  age: []
});

for the form listener :

 this.refClientForm.valueChanges.subscribe(values => console.log(values))

but i got always all form values.

AHmedRef
  • 2,555
  • 12
  • 43
  • 75
  • Possible duplicate of [Angular 2 getting only the dirty values in a controlgroup](https://stackoverflow.com/questions/37342444/angular-2-getting-only-the-dirty-values-in-a-controlgroup) – JayChase Jun 05 '19 at 02:45

4 Answers4

23

You can check all controls for dirty-flag. See https://angular.io/api/forms/FormControl

getDirtyValues(form: any) {
        let dirtyValues = {};

        Object.keys(form.controls)
            .forEach(key => {
                let currentControl = form.controls[key];

                if (currentControl.dirty) {
                    if (currentControl.controls)
                        dirtyValues[key] = this.getDirtyValues(currentControl);
                    else
                        dirtyValues[key] = currentControl.value;
                }
            });

        return dirtyValues;
}
AHmedRef
  • 2,555
  • 12
  • 43
  • 75
J. Knabenschuh
  • 747
  • 4
  • 15
5

Better answer found here:

Angular 2 Reactive Forms only get the value from the changed control

this.imagSub = this.imagingForm.valueChanges.pipe(
    pairwise(),
    map(([oldState, newState]) => {
      let changes = {};
      for (const key in newState) {
        if (oldState[key] !== newState[key] && 
            oldState[key] !== undefined) {
          changes[key] = newState[key];
        }
      }
      return changes;
    }),
    filter(changes => Object.keys(changes).length !== 0 && !this.imagingForm.invalid)
  ).subscribe(
    value => {
      console.log("Form has changed:", value);
    }
  );
ktamlyn
  • 4,519
  • 2
  • 30
  • 41
  • This was what I needed, as I just want the "latest" changed value instead of "all" changed values. I also like the rxJs utilities used for this. – Justus Romijn Mar 30 '23 at 08:29
  • With this answer, the code inside subscribe is not executed for the the very first value change – Rivosoa Jun 15 '23 at 08:55
1

There is a simple way to check if any control is dirty in the reactive form.

getUpdatedValues() {
 const updatedFormValues = {};
 this.form['_forEachChild']((control, name) => {
  if (control.dirty) {
      this.updatedFormValues[name] = control.value;
  }
});
console.log(this.updatedFormValues);
bhavik shah
  • 744
  • 7
  • 11
-1

use pairwise() operator with startWith(this.refClientForm.value) operator then form valueChanges will emit on first try

Sayax
  • 1
  • 2
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 26 '21 at 10:09