ngx-ui-switch icon indicating copy to clipboard operation
ngx-ui-switch copied to clipboard

ReactiveForms - patchValue and setValue does not work correctly with option emitEvent false

Open blazekv opened this issue 1 year ago • 3 comments

If ui-switch is part of reactive forms and there is set or patch method used with option emit event false it does not work.

Example code for demo:

demo.component.ts

  constructor(private fb: NonNullableFormBuilder) {
    this.form = this.fb.group({
      test: [false]
    })
    this.form.valueChanges.subscribe((value) => console.log('Changed', value));
  }
  
    test() {
       this.form.patchValue({test: false}, {emitEvent: false})
    }

demo.component.html

    <div [formGroup]="form">
      <ui-switch formControlName="test" checked [ariaLabel]="'checked'"></ui-switch>
    </div>
    <button (click)="test()">change</button>

Expected behaviour: If button change is clicked there is no output in console (because of emitEvent is set to false)

Actual behaviour: If button change is clicked there is "Changed" output in console (emitEvent option does not work)

Reason of this strange behaviour is because onChange is called while setting value (in writeValue method), but it was added because some kind of bug - https://github.com/webcat12345/ngx-ui-switch/commit/1382bb140422c5efca4df9d6e15030da3535c2e2

blazekv avatar Jan 15 '24 13:01 blazekv

Took me a while to find out it came from ui-switch. I confirm, emitEvent is not respected.

jeandat avatar May 16 '24 10:05 jeandat

Indeed in code there is this:

writeValue(obj: any): void {
    if (obj !== this.checked) {
      this.checked = !!obj;
    }

    this.onChangeCallback(this.checked); // <---- HERE
    if (this.cdr) {
      this.cdr.markForCheck();
    }
  }

Why would you want to call the CVA callback when you receive a new value? You should call it only when the internal value has changed after a user action.

jeandat avatar May 24 '24 09:05 jeandat