hardFrontend

How do you build a custom form control by implementing the ControlValueAccessor interface?

994 views
01

Understand the problem

Explain how to hook up custom UI components to Reactive Forms.

formscustom-control
02

Attempt it yourself

Sketch your approach before reading the solution — that's what interviews test.

Stuck? AI Nudge Available

Get a conceptual hint to guide your logic without spoiling the final implementation.

03

Study the solution

The solution is waiting

Give it an honest attempt first — then compare your thinking with the full walkthrough.

04

Read the code

Implementing a custom star-rating form control
import { Component, Provider, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

const STAR_PROVIDER: Provider = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => StarRatingComponent),
  multi: true
};

@Component({
  selector: 'app-star-rating',
  standalone: true,
  providers: [STAR_PROVIDER],
  template: '<div class="stars">' +
    '  @for (star of [1, 2, 3, 4, 5]; track star) {' +
    '    <span (click)="rate(star)">{{ rating >= star ? \'★\' : \'☆\' }}</span>' +
    '  }' +
    '</div>'
})
export class StarRatingComponent implements ControlValueAccessor {
  rating = 0;
  onChange = (val: number) => {};
  onTouched = () => {};
  disabled = false;

  writeValue(value: number): void {
    this.rating = value || 0;
  }

  registerOnChange(fn: any): void { this.onChange = fn; }
  registerOnTouched(fn: any): void { this.onTouched = fn; }
  setDisabledState?(isDisabled: boolean): void { this.disabled = isDisabled; }

  rate(val: number) {
    if (!this.disabled) {
      this.rating = val;
      this.onChange(val);
      this.onTouched();
    }
  }
}
05

Join the discussion

Discussion (0)

Sign in to join the discussion.

No responses yet. Be the first to share what you think.