Angular provides built-in validators and a clean API for writing custom synchronous and asynchronous validators.
import { Validators } from '@angular/forms';
this.fb.group({
username: ['', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(20),
Validators.pattern(/^[a-zA-Z0-9_]+$/),
]],
age: [null, [Validators.required, Validators.min(18), Validators.max(120)]],
site: ['', Validators.compose([Validators.required, Validators.url])],
});
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
export function noSpacesValidator(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
return /\s/.test(control.value)
? { noSpaces: { value: control.value } }
: null;
};
}
// Usage
username: ['', [Validators.required, noSpacesValidator()]]
export function passwordMatchValidator(control: AbstractControl): ValidationErrors | null {
const password = control.get('password');
const confirm = control.get('confirmPassword');
if (password && confirm && password.value !== confirm.value) {
return { passwordMismatch: true };
}
return null;
}
// Apply at group level
this.fb.group({ password: [''], confirmPassword: [''] }, { validators: passwordMatchValidator })
export function usernameAvailable(service: UserService): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors | null> => {
return service.checkUsername(control.value).pipe(
debounceTime(400),
map(taken => taken ? { usernameTaken: true } : null),
catchError(() => of(null))
);
};
}