Validation on Custom Form Control
We use the Validator
interface to add custom validation to our form controllers. The Validator
interface provides the following two methods responsible for the form validation.
interface Validator {
validate(control: AbstractControl): ValidationErrors | null;
registerOnValidatorChange?(fn: () => void): void;
}
validate
— check if the provided control is valid and returnnull
if valid andValidationError
if it has errors.registerOnValidatorChange
— register a call-back method to check if the form control values have changed. External changes will trigger validation, but we need to notify about internal changes to validate.
class EmailValidator implements Validator {
private _onChange?: () => void;
@Input()
set email(value: boolean | string) {
if (this._onChange) this._onChange();
}
validate(control: AbstractControl): ValidationErrors | null {
return emailValidator(control);
}
registerOnValidatorChange(fn: () => void): void {
this._onChange = fn;
}
}
We also have an AsyncValidator
to implement asynchronous validations. The success of synchronous validators will trigger asynchronous validations. So, if we've any failing synchronous validators, then asynchronous will not be triggered.
interface AsyncValidator extends Validator {
validate(
control: AbstractControl
): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>;
}
The observable returned via validate
must be finite, meaning it must complete at some point.