Tristan MARIE
Tristan MARIE

Reputation: 117

Patch only pristine values

I need to patch the values of only the pristine properties of my reactive form in Angular.

I have a websocket service that sends me updates done to a user, and would like to patch the form according to the payload I receive, but not changing dirty properties

This is the code doing the update:

this.messageService.subscribe('updates', 'user', frame => {
   this.userProfileForm.patchValue(frame.payload)
})

Is there an easy way to do that or do I have to remove all dirty fields from my update object ?

Upvotes: 1

Views: 874

Answers (1)

Tristan MARIE
Tristan MARIE

Reputation: 117

I ended up defining 2 new classes :

import {FormGroup} from "@angular/forms";

export class PristineAwareFormGroup extends FormGroup {
  override patchValue(value: { [p: string]: any }, options?: { onlySelf?: boolean; emitEvent?: boolean }) {
    if (value == null /* both `null` and `undefined` */)
      return;
    Object.keys(value).forEach(name => {
      if (this.controls[name] && this.controls[name].pristine) {
        this.controls[name].patchValue(value[name], {
          onlySelf: true,
          emitEvent: options?.emitEvent
        });
      }
    });
    this.updateValueAndValidity(options);
  }
}

and

import {FormControl} from "@angular/forms";

export class PristineAwareFormControl extends FormControl {
  override patchValue(value: any, options?: { onlySelf?: boolean; emitEvent?: boolean; emitModelToViewChange?: boolean; emitViewToModelChange?: boolean }) {
    if (this.pristine) {
      this.setValue(value, options);
    }
  }
}

I can now create my forms like this :

  public userProfileForm = new PristineAwareFormGroup({
    name: new PristineAwareFormControl('', Validators.required),
    civilStatus: new PristineAwareFormGroup({
      firstName: new PristineAwareFormControl(),
      lastName: new PristineAwareFormControl(),
      title: new PristineAwareFormControl(),
      birthName: new PristineAwareFormControl(),
      additionalNames: new PristineAwareFormControl('')
    })
  })

This works wonderfully well

Upvotes: 2

Related Questions