Validation in Custom Controls
Provide validators from custom controls.
Validation in Custom Controls is a free Angular Academy lesson on CoddyKit — lesson 4 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.
Self-Validating Controls
A custom control can carry its own validation logic by implementing the Validator interface and registering with NG_VALIDATORS, so consumers get validity for free.
The Validator Interface
Validator requires a validate method that returns ValidationErrors (an error map) or null when valid.
import { Validator, ValidationErrors, AbstractControl } from '@angular/forms';
export class RatingComponent implements Validator {
validate(control: AbstractControl): ValidationErrors | null {
return control.value > 0 ? null : { required: true };
}
}Registering NG_VALIDATORS
Add a second multi-provider for NG_VALIDATORS alongside NG_VALUE_ACCESSOR, again using forwardRef.
import { NG_VALIDATORS } from '@angular/forms';
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RatingComponent), multi: true },
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => RatingComponent), multi: true }
]Returning Error Maps
The error map keys become entries in control.errors. Use descriptive keys and optional payloads so templates can show targeted messages.
validate(control: AbstractControl): ValidationErrors | null {
const v = control.value;
if (v == null) return { required: true };
if (v < this.min) return { min: { required: this.min, actual: v } };
return null;
}Consuming Errors
Templates read control.errors just like for built-in validators, displaying messages when the control is invalid and touched.
<small *ngIf="form.controls.stars.errors?.['required']">Pick a rating</small>Combining With External Validators
Validators from the control and validators passed by the consumer (in the reactive form) both run and merge. Your control's rules add to, not replace, the form's rules.
stars: [0, [Validators.required]] // plus the control's own validate()Dynamic Validation
If validation depends on an input that changes, call the registered change callback to tell Angular to re-run validation.
private onValidatorChange: () => void = () => {};
registerOnValidatorChange(fn: () => void) { this.onValidatorChange = fn; }
@Input() set min(v: number) { this._min = v; this.onValidatorChange(); }Async Validation
For server checks implement AsyncValidator with a validate returning an Observable or Promise of errors, and register with NG_ASYNC_VALIDATORS.
validate(control: AbstractControl): Observable<ValidationErrors | null> {
return this.api.isUnique(control.value).pipe(
map(ok => ok ? null : { taken: true })
);
}Keep It Focused
Put only validation that is intrinsic to the control inside it (a rating must be greater than zero). Leave business-specific rules to the consuming form for reusability.
Testing Validation
Unit test validate directly by passing a fake control with a value and asserting the returned error map or null.
it('requires a rating', () => {
const c = new FormControl(0);
expect(component.validate(c)).toEqual({ required: true });
});Full Custom Control
With value accessor, disabled, touched, and validation all implemented, your component is a complete, reusable form control indistinguishable from native inputs to consumers.
Quick Check
Check your validation knowledge.
Recap
You added validation by implementing Validator.validate, registering NG_VALIDATORS, returning error maps, supporting dynamic re-validation via registerOnValidatorChange, and optionally AsyncValidator with NG_ASYNC_VALIDATORS for a fully integrated custom control.
Frequently asked questions
Is the “Validation in Custom Controls” lesson free?
Yes — the full text of “Validation in Custom Controls” 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 “Validation in Custom Controls”?
Provide validators from custom controls. 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 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Validation in Custom Controls” 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