3
votes

Why when I use ControlValueAccessor the value doesn't update and reflect with reactive form?

In my application I have a form:

 profileForm = new FormGroup({
    name: new FormControl(1),
  });

And I pass name from profileForm using formControlName into my-comp (ControlValueAccessor) component.

Now, when I click on the button: changeValueFromMyApp from the app component to change the name to 2 using patchValue is update the profileForm and the value inside the my-comp component. (because it invoke the writeValue method).

But when I click inside my-comp component on changeValueFromMyComp button to change the value to 4, the parent change ( profileForm) but the change doesn't reflect to my-comp. Why? What is missing here? how to make it work?

app.ts

import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';

@Component({
  selector: 'my-app',
  template:`
    <form [formGroup]="profileForm">
      <my-comp formControlName="name"></my-comp>

    </form>

    form value: {{ profileForm.value | json }}
    <button (click)="changeValueFromMyApp()">changeValueFromMyApp</button>
  `

})
export class AppComponent  {
  profileForm = new FormGroup({
    name: new FormControl(1),
  });


  changeValueFromMyApp() {
    this.profileForm.patchValue({
      name: 2
    });
  }
}

my-comp.ts:

import { Component, forwardRef } from '@angular/core';
import { FormGroup, FormControl, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'my-comp',
  template:`
    value inside the component is: {{value | json}}

    <button (click)="changeValueFromMyComp()">change the value to 4</button>

  `,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => MyComp),
      multi: true
    }
  ]
})
export class MyComp implements ControlValueAccessor {

  value;
  onChange = () => {};
  onTouch = () => {};

  writeValue(value) {
    // this is happends when the parent change the value?
    this.value = value;
  }

  registerOnChange(fn) {
    this.onChange = fn;
  }

  registerOnTouch(fn) {
    this.onTouch = fn;
  }

  changeValueFromMyComp() {
    this.onChange(4);
  }
}
1

1 Answers

2
votes

you need to update the variable 'value' here (my-comp.ts):

changeValueFromMyComp() {
    this.onChange(4);
    this.value = 4;
}

The onChange function doesnt update the value automatically.