The ControlValueAccessor Interface
Connect a custom widget to Angular forms.
The ControlValueAccessor Interface is a free Angular Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Angular Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Custom Controls
Angular forms work with native inputs out of the box. To make your own component (a rating widget, color picker, toggle) usable with ngModel and formControlName, it must implement ControlValueAccessor.
The Bridge
ControlValueAccessor (CVA) is the bridge between Angular's form model and your component's view. It defines how the model writes values in and how user changes flow back out.
The Interface
CVA requires four methods: writeValue, registerOnChange, registerOnTouched, and the optional setDisabledState.
interface ControlValueAccessor {
writeValue(value: any): void;
registerOnChange(fn: (v: any) => void): void;
registerOnTouched(fn: () => void): void;
setDisabledState?(isDisabled: boolean): void;
}Registering The Provider
Tell Angular your component is a value accessor by providing NG_VALUE_ACCESSOR with multi: true and useExisting pointing to the component.
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { forwardRef } from '@angular/core';
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RatingComponent),
multi: true
}]Why forwardRef
forwardRef is needed because the class references itself in its own metadata before the class is defined. It defers resolution until the class exists.
Component Skeleton
A custom control declares the provider and implements the interface methods. The class holds the current value internally.
@Component({
selector: 'app-rating',
providers: [/* NG_VALUE_ACCESSOR ... */]
})
export class RatingComponent implements ControlValueAccessor {
value = 0;
// writeValue, registerOnChange, registerOnTouched ...
}Using It Like Native
Once CVA is implemented, your component plugs into template-driven and reactive forms exactly like a native input.
<app-rating formControlName="stars"></app-rating>
<!-- or -->
<app-rating [(ngModel)]="stars"></app-rating>Two Directions Of Data
Model-to-view flows through writeValue (Angular pushes the form value in). View-to-model flows through the callback registered in registerOnChange (you push user changes out).
Touched Tracking
Form validation UX depends on touched state. You notify Angular via the callback from registerOnTouched, typically on blur.
Disabled State
When the form disables the control (control.disable()), Angular calls setDisabledState so your component can reflect it visually and ignore input.
Roadmap
The next lessons implement each piece: writing and registering values, handling disabled and touched states, and adding validation. Together they make a fully integrated custom control.
Quick Check
Check your CVA basics.
Recap
You learned that ControlValueAccessor connects custom components to Angular forms via four methods, registered through NG_VALUE_ACCESSOR with forwardRef and multi: true. Next, you implement writing and registering values.
Frequently asked questions
Is the “The ControlValueAccessor Interface” lesson free?
Yes — the full text of “The ControlValueAccessor Interface” is free to read here on the web, and the Angular Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Angular Academy course, upgrade to CoddyKit PRO.
What will I learn in “The ControlValueAccessor Interface”?
Connect a custom widget to Angular forms. You practise Angular Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Angular Academy?
No prior experience is required. Angular Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “The ControlValueAccessor Interface” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Angular Academy lesson?
Yes. Every Angular Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- The ControlValueAccessor Interface
- Writing and Registering Values
- Handling Disabled and Touched States
- Validation in Custom Controls