Angular Custom Validators
Learn Angular Custom Validators with synchronous validators, asynchronous validators, reusable validation functions, cross-field validation, FormGroup validation, architecture diagrams, enterprise examples, best practices, and interview questions.
Angular provides many built-in validators like:
- required
- minlength
- maxlength
- pattern
However, real-world enterprise applications often require custom business validations that cannot be handled using built-in validators.
Examples include:
- Password Strength
- Confirm Password
- PAN Number Validation
- Employee ID Validation
- Age Validation
- Username Availability
- Credit Card Validation
- IFSC Code Validation
- Account Number Validation
Custom Validators are one of the most frequently asked Angular Reactive Forms interview topics.
Table of Contents
- What are Custom Validators?
- Why Use Custom Validators?
- ValidatorFn
- Creating a Synchronous Validator
- Using Custom Validators
- Cross-Field Validation
- Async Validators
- Reusable Validators
- Enterprise Banking Example
- Performance Best Practices
- Common Mistakes
- Top 10 Interview Questions
- Summary
What are Custom Validators?
A Custom Validator is a function that validates a form control according to application-specific business rules.
It returns:
null→ Validation passedValidationErrors→ Validation failed
Example
Password
↓
Validator
↓
Valid
or
Invalid
Custom Validator Architecture
flowchart TD
User
User --> Input
Input --> FormControl
FormControl --> Validator
Validator --> Valid
Validator --> Invalid
Valid --> Submit
Invalid --> ErrorMessage
Why Use Custom Validators?
Built-in validators cannot validate rules like:
- Password must contain uppercase letters
- Age must be greater than 18
- PAN format validation
- Username uniqueness
- Matching passwords
- Business-specific IDs
Custom validators solve these scenarios.
ValidatorFn
Angular provides the ValidatorFn interface.
export interface ValidatorFn {
(control: AbstractControl):
ValidationErrors | null;
}
Every custom validator follows this contract.
Validation Flow
flowchart LR
Input
Input --> FormControl
FormControl --> ValidatorFn
ValidatorFn --> Result
Result --> UI
Creating a Simple Validator
Example: Minimum Age Validator
import {
AbstractControl,
ValidationErrors
} from '@angular/forms';
export function
minimumAgeValidator(
control: AbstractControl
): ValidationErrors | null {
const age =
control.value;
if(age < 18){
return {
minimumAge:true
};
}
return null;
}
Using the Validator
import {
FormBuilder
} from '@angular/forms';
constructor(
private fb:FormBuilder
){}
registrationForm =
this.fb.group({
age:[
'',
minimumAgeValidator
]
});
Angular automatically executes the validator whenever the value changes.
Validator Execution
sequenceDiagram
participant User
participant FormControl
participant Validator
participant UI
User->>FormControl: Enter Value
FormControl->>Validator: Validate
Validator-->>UI: Result
Displaying Validation Errors
<input
type="number"
formControlName="age">
<div
*ngIf="
registrationForm
.get('age')
?.errors?.['minimumAge']
">
Minimum age is 18.
</div>
Password Strength Validator
export function
passwordStrengthValidator(
control: AbstractControl
): ValidationErrors | null {
const password =
control.value;
const strongPassword =
/^(?=.*[A-Z])
(?=.*[a-z])
(?=.*[0-9])
(?=.*[@$!%*?&]).{8,}$/x;
if(
!strongPassword.test(password)
){
return {
weakPassword:true
};
}
return null;
}
Usage
password:[
'',
passwordStrengthValidator
]
Requirements
- Uppercase letter
- Lowercase letter
- Number
- Special character
- Minimum 8 characters
Note: JavaScript regular expressions do not support the
/x(extended) flag. Write the pattern on a single line in production code, for example:/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[@$!%*?&]).{8,}$/
Password Validation Flow
flowchart TD
Password
Password --> Validator
Validator --> Strong
Validator --> Weak
Weak --> Error
Strong --> Submit
Cross-Field Validation
Some validations require multiple controls.
Example
- Password
- Confirm Password
Validator
import {
AbstractControl,
ValidationErrors
} from '@angular/forms';
export function
passwordMatchValidator(
group: AbstractControl
):
ValidationErrors | null {
const password =
group.get('password')?.value;
const confirm =
group.get('confirmPassword')?.value;
if(password !== confirm){
return {
passwordMismatch:true
};
}
return null;
}
Apply
this.fb.group({
password:[''],
confirmPassword:['']
},
{
validators:
passwordMatchValidator
});
Cross-Field Validation Architecture
flowchart TD
FormGroup
FormGroup --> Password
FormGroup --> ConfirmPassword
Password --> Validator
ConfirmPassword --> Validator
Validator --> Result
Asynchronous Validators
Async validators validate data against external systems.
Example
- Username availability
- Email uniqueness
- Employee ID lookup
- Customer number validation
Async Validator Example
import {
AbstractControl,
AsyncValidatorFn
} from '@angular/forms';
import {
map
} from 'rxjs/operators';
function usernameValidator(
service:UserService
): AsyncValidatorFn {
return (
control:AbstractControl
)=>
service
.checkUsername(
control.value
)
.pipe(
map(
exists=>
exists
?
{
usernameTaken:true
}
:
null
)
);
}
Async Validation Flow
flowchart LR
Input
Input --> AsyncValidator
AsyncValidator --> RESTAPI
RESTAPI --> Database
Database --> Result
Result --> UI
Reusable Validators
Create a shared validators folder.
validators/
password.validator.ts
email.validator.ts
age.validator.ts
pan.validator.ts
account.validator.ts
Benefits
- Reuse
- Easy testing
- Better maintenance
- Cleaner architecture
Enterprise Banking Example
Loan Application
Fields
- PAN
- Aadhaar
- IFSC
- Account Number
- Customer Age
- Income
Architecture
flowchart TD
Customer
Customer --> FormGroup
FormGroup --> Validators
Validators --> BankingAPI
BankingAPI --> Database
Database --> ValidationResult
Examples
- Customer age ≥ 18
- PAN format validation
- Account number validation
- IFSC validation
- Customer eligibility
- Duplicate account detection
Validation Order
flowchart TD
Input
Input --> BuiltInValidator
BuiltInValidator --> CustomValidator
CustomValidator --> AsyncValidator
AsyncValidator --> Submit
Performance Best Practices
| Practice | Benefit |
|---|---|
| Keep validators pure | Predictable behavior |
| Reuse validator functions | Easier maintenance |
| Avoid HTTP calls in synchronous validators | Better performance |
| Use async validators only when required | Reduce server load |
| Return meaningful error keys | Easier error handling |
| Unit test validators | Higher reliability |
Common Mistakes
Modifying Control Values
Validators should validate only.
Avoid
control.setValue(...);
inside validators.
Making HTTP Calls in ValidatorFn
Synchronous validators should never perform HTTP calls.
Use an AsyncValidatorFn instead.
Hardcoding Error Messages
Return an error key such as:
{
weakPassword:true
}
Display user-friendly messages in the template.
Duplicating Validators
Reuse validator functions across multiple forms.
Putting Business Logic Inside Components
Keep validation logic inside reusable validator functions rather than components.
Best Practices
- Keep validators reusable.
- Return descriptive error keys.
- Separate synchronous and asynchronous validation.
- Unit test validator functions.
- Group validators by feature.
- Keep validators pure and side-effect free.
- Prefer cross-field validators for related controls.
- Use async validators only when external validation is necessary.
Advantages
| Feature | Benefit |
|---|---|
| Business Validation | Supports custom rules |
| Reusable | Less duplication |
| Testable | Easy unit testing |
| Clean Architecture | Better separation of concerns |
| Async Support | Server-side validation |
| Enterprise Ready | Large-scale applications |
Top 10 Angular Custom Validators Interview Questions
1. What are Custom Validators?
Answer
Custom Validators are user-defined validation functions that implement business-specific validation rules not covered by Angular's built-in validators.
2. What does a Custom Validator return?
Answer
A validator returns:
null→ Validation passedValidationErrors→ Validation failed
3. What is ValidatorFn?
Answer
ValidatorFn is a function type that accepts an AbstractControl and returns either ValidationErrors or null.
4. What is AsyncValidatorFn?
Answer
AsyncValidatorFn is used for asynchronous validation, such as checking username availability or validating data against a server.
5. What is Cross-Field Validation?
Answer
Cross-field validation validates multiple controls together, such as ensuring that password and confirmPassword contain the same value.
6. Where should Custom Validators be stored?
Answer
Store them in a dedicated validators folder so they can be reused across multiple forms and applications.
7. Can Custom Validators be reused?
Answer
Yes.
A single validator function can be applied to multiple controls or forms.
8. What are common Custom Validator examples?
Answer
- Password strength
- Age validation
- PAN validation
- Username availability
- Email uniqueness
- Account number validation
- IFSC validation
- Password confirmation
9. What are Custom Validator best practices?
Answer
- Keep validators pure.
- Return meaningful error keys.
- Reuse validator functions.
- Unit test validation logic.
- Separate sync and async validation.
10. What are common mistakes?
Answer
- Updating control values inside validators.
- Making HTTP calls in synchronous validators.
- Hardcoding error messages.
- Duplicating validator code.
- Mixing validation logic with business logic.
Interview Cheat Sheet
| Topic | Remember |
|---|---|
| Sync Validator | ValidatorFn |
| Async Validator | AsyncValidatorFn |
| Success | null |
| Failure | ValidationErrors |
| Cross-Field | FormGroup Validator |
| Password Match | Group validation |
| Username Check | Async Validator |
| Reusability | Shared validator folder |
| Best Practice | Pure functions |
| Enterprise Use | Business rules |
Summary
Angular Custom Validators extend the capabilities of Reactive Forms by enabling application-specific validation rules beyond Angular's built-in validators. Whether validating password strength, enforcing business rules, comparing multiple fields, or checking server-side data through asynchronous validation, custom validators help build secure, maintainable, and enterprise-ready forms. By keeping validators reusable, pure, and well-tested, developers can create scalable validation frameworks that are easy to maintain.
Key Takeaways
- ✔ Custom Validators implement business-specific validation.
- ✔
ValidatorFnis used for synchronous validation. - ✔
AsyncValidatorFnis used for server-side validation. - ✔ Return
nullfor valid input andValidationErrorsfor invalid input. - ✔ Use cross-field validators for related controls.
- ✔ Keep validators pure and reusable.
- ✔ Store validators in a shared folder.
- ✔ Unit test validation logic.
- ✔ Avoid side effects inside validators.
- ✔ Custom Validators are a core Angular Reactive Forms interview topic.
Next Article
➡️ 57-FormArray-QA.md