Discover how custom validators can save you from messy, repetitive form checks!
Why Custom validators in Angular? - Purpose & Use Cases
Imagine you have a form where users must enter a username that is not only filled but also unique and follows special rules like no spaces or special characters.
You try to check all these rules manually every time the user types something.
Manually checking each rule every time is slow and messy.
You have to write repeated code for each input, and it's easy to forget or make mistakes.
Also, the form won't update properly if you don't handle errors right, confusing users.
Custom validators let you write reusable, clear rules that Angular runs automatically on your form inputs.
This keeps your code clean and your form responsive, showing errors exactly when needed.
if(username.includes(' ')) { showError('No spaces allowed'); }
function noSpacesValidator(control) { return control.value && control.value.includes(' ') ? { 'noSpaces': true } : null; }You can create smart, reusable checks that keep your forms user-friendly and error-free.
Think of a signup form that blocks usernames with spaces or special characters instantly, guiding users to fix mistakes before submitting.
Manual validation is slow and error-prone.
Custom validators automate and simplify input checks.
They improve user experience by showing clear, timely errors.
Practice
Solution
Step 1: Understand Angular validator return values
Angular custom validators returnnullwhen the input passes validation, meaning no errors.Step 2: Identify the valid return for no errors
Returningnullsignals the form control is valid, while any object means invalid.Final Answer:
null -> Option DQuick Check:
Valid input returns null [OK]
- Returning true or false instead of null or error object
- Returning empty string instead of null
- Confusing valid with invalid return values
Solution
Step 1: Recall Angular validator function signature
A synchronous custom validator takes an AbstractControl and returns ValidationErrors or null.Step 2: Match the correct function signature
function myValidator(control: AbstractControl): ValidationErrors | null matches the required signature exactly, others do not fit Angular patterns.Final Answer:
function myValidator(control: AbstractControl): ValidationErrors | null -> Option BQuick Check:
Validator signature = function myValidator(control: AbstractControl): ValidationErrors | null [OK]
- Using wrong parameter types like string or Event
- Returning boolean instead of error object or null
- Missing return type or returning void
function alphaOnly(control: AbstractControl) {
const valid = /^[a-zA-Z]+$/.test(control.value);
return valid ? null : { alphaOnly: true };
}Solution
Step 1: Analyze the regex test on input 'abc123'
The regex /^[a-zA-Z]+$/ matches only letters. 'abc123' contains digits, so test returns false.Step 2: Determine validator return value
Since test is false, the validator returns the error object { alphaOnly: true } indicating invalid input.Final Answer:
{ alphaOnly: true } -> Option AQuick Check:
Input with digits fails alphaOnly validator [OK]
- Assuming digits pass the regex
- Confusing true/false return values
- Expecting null for invalid input
function minLengthFive(control: AbstractControl) {
if (control.value.length < 5) {
return { minLengthFive: true };
}
}Solution
Step 1: Check for runtime errors
The code accesses control.value.length without checking if control.value is null or undefined, causing TypeError when value is null (common for new FormControls).Step 2: Angular validator best practice
Always check if (control.value == null) return null; before accessing properties like length. Explicit return null; for valid cases is also recommended.Final Answer:
Using control.value.length without checking null -> Option CQuick Check:
control.value can be null causing crash [OK]
- Not checking control.value for null before .length
- Returning undefined instead of null for valid input
- Confusing error object keys with validator names
Solution
Step 1: Understand password requirements
The password must have at least one uppercase, one lowercase, and one digit character.Step 2: Analyze each option's logic
function passwordValidator(control: AbstractControl) { const val = control.value || ''; const hasUpper = /[A-Z]/.test(val); const hasLower = /[a-z]/.test(val); const hasDigit = /\d/.test(val); return hasUpper && hasLower && hasDigit ? null : { passwordStrength: true }; } correctly tests all three conditions and returns null if all pass, error object otherwise. function passwordValidator(control: AbstractControl) { if (!control.value.match(/[A-Z]/) || !control.value.match(/[a-z]/) || !control.value.match(/[0-9]/)) { return null; } return { passwordStrength: true }; } reverses logic, returning null on failure. The remaining options check unrelated conditions.Final Answer:
function passwordValidator(control: AbstractControl) { const val = control.value || ''; const hasUpper = /[A-Z]/.test(val); const hasLower = /[a-z]/.test(val); const hasDigit = /\d/.test(val); return hasUpper && hasLower && hasDigit ? null : { passwordStrength: true }; } -> Option AQuick Check:
All conditions true returns null, else error [OK]
- Returning null on invalid input
- Checking only length or spaces, not required chars
- Mixing up logic conditions in if statements
Ready to prove it?
Pass the test and this pattern moves unknown
