Search code examples
angularangular2-changedetectionangular-controlvalueaccessor

Value Accessor issues on a radio button component


So I'm trying to make just a really simple and clean radio button component that can be used with value accessor to be used in the common angular forms scenarios with FormsModule, ReactiveFormsModule and using changeDetectionStrategy.OnPush but I've ran into the issue(s) you can see ON THIS Stackblitz where I'm getting unexpected results which I understand is probably me missing something since it's been a long time since I've done a custom radio.

When it first loads, you get the radio outlines but no labels until you click something and writeValue and onModelChange are undefined while I get a No value accessor for form control with name: error. So could use another pair of eyes so I can use the instance with good 'ol ngModel, formControlName, FormBuilder.

You'll see in the Stackblitz the value accessor is there and implementing ControlValueAccessor so I'm a bit confused since I've done the same approach with another component recently just fine. I could copy/paste parts of the blitz here but figured the example should be enough however if not just let me know.


Solution

  • I have made few changes to your code on Stackblitz, please check and let me know if it resolves your issue.

    Below is the summary of the changes done:

    • Introduced a new RadioButtonComponent property named internalValue and used it to bind to [ngModel]. Also updating it's value within writeValue() method.
    • Commented the code within writeValue related to this.checked and manual update to input element's checked property. That should automatically be handled by Angular Forms API.
    • Within RadioButtonComponent html template removed [attr.checked] binding and instead of using attribute binding for name and value, simply used property binding.
    • In app.component.html instead of using property binding, used two-way binding [(ngModel)] syntax, so that the value gets reflected when you print it using ngModel: {{testing}}

    You may change/tweak other things too, but hopefully the above changes will help you get going.