1
votes

Im trying to create my own radio button component with two ways binding, and use it in another component:

my-custom-component.ts:

import { Component, Input, Output, DoCheck, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-buttons-radio',
  templateUrl: './buttons-radio.component.html',
  styleUrls: ['./buttons-radio.component.css'],
})

export class ButtonsRadioComponent implements DoCheck {
  @Input() options: ButtonRadioItem[];
  @Input() value;
  @Output() valueChange: EventEmitter<number> = new EventEmitter();

  ngDoCheck() {
    this.valueChange.next(this.value);
  }
}

my-custom-component.html:

<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" [(ngModel)]="value">
  <ng-container *ngFor="let v of options">
    <label ngbButtonLabel class="btn-primary">
      <input ngbButton type="radio" [(value)]="v.value">{{v.key}}
    </label>
  </ng-container>
</div>

usage in my-parent-component.html:

<app-buttons-radio [options]="sourceButtonsRadio" [(value)]="sourceValue"></app-buttons-radio>

Everything works fine: the component is shown as expected, the value of sourceValue is changing, but each time when I click on radio button I get an error in the console

enter image description here

I've already tried to inject changeDetectorRef into my custom component and use changeDetectorRef.detectChanges() method, but still got an error. How can I handle this error?

1
You should really not use ngDoCheck, better would be to use ngOnChanges. Also look into using the OnPush change detection strategy when creating components - Poul Kruijt
@poul-kruijt ngOnChanges doesn’t catch changes when I click on buttons - krabcore
but those buttons are inside the component, so you should make the component handle that change, and not depend on ngDoCheck. This hook runs way too many times, and will emit valueChange constantly - Poul Kruijt

1 Answers

0
votes

Thanks to @poul-kruijt, changed my code according suggestions in comments. correct code:

my-custom-component.ts:

...
export class ButtonsRadioComponent implements DoCheck {
  @Input() options: ButtonRadioItem[];
  @Input() value;
  @Output() valueChange: EventEmitter<number> = new EventEmitter();

  ngDoCheck() {
    this.valueChange.next(this.value);
  }
}

my-custom-component.html:

<div class="btn-group btn-group-toggle"
     ngbRadioGroup name="radioBasic" [(ngModel)]="value" (ngModelChange)="valueChanged($event)">
      ...
</div>

usage in my-parent-component.html: