AsyncCustomValidator
@ng-forge/dynamic-forms
Async custom validator configuration using Angular's resource-based API
Angular's validateAsync uses the resource API for async validation, which provides better integration with Signal Forms lifecycle management.
Structure:
- params: Function that computes params from field context
- factory: Function that creates a ResourceRef from params signal
- onSuccess: Maps successful resource result to validation errors
- onError: Optional handler for resource errors (network failures, etc.)
Use Cases: - Database lookups via services with resource API - Complex async business logic with Angular resources - Any async operation using Angular's resource pattern
Note: For HTTP validation, prefer HttpCustomValidator which provides
a simpler API specifically designed for HTTP requests.
Signature
interface AsyncCustomValidator<
TValue = unknown,
TParams = unknown,
TResult = unknown
>Type Parameters
| Name | Constraint | Default | Description |
|---|---|---|---|
TValue | - | unknown | - |
TParams | - | unknown | - |
TResult | - | unknown | - |
Properties
| Name | Type | Description |
|---|---|---|
params | (ctx: FieldContext<TValue>, config?: Record<string, unknown>) => TParams | Function that receives field context and returns resource params. Params will be tracked as a signal and trigger resource reload when changed. |
factory | (params: Signal<TParams>) => ResourceRef<TResult> | Function that creates a ResourceRef from the params signal. The resource will be automatically managed by Angular's lifecycle. |
onSuccess ? | (result: TResult, ctx: FieldContext<TValue>) => TreeValidationResult | Optional function to map successful resource result to validation errors. Return null if validation passes, or ValidationError/ValidationError[] if validation fails. |
onError ? | (error: unknown, ctx: FieldContext<TValue>) => any | Optional error handler for resource errors (network failures, etc.). Return null to ignore the error, or ValidationError to display it to the user. |
Examples
const checkUsernameAvailable: AsyncCustomValidator<string> = {
params: (ctx) => ({ username: ctx.value() }),
factory: (params) => {
const injector = inject(Injector);
return resource({
request: () => params(),
loader: ({ request }) => {
if (!request?.username) return null;
const service = injector.get(UserService);
return firstValueFrom(service.checkAvailability(request.username));
}
});
},
onSuccess: (result, ctx) => {
if (!result) return null;
return result.available ? null : { kind: 'usernameTaken' };
},
onError: (error, ctx) => {
console.error('Availability check failed:', error);
return null; // Don't block form on network errors
}
};packages/dynamic-forms/src/lib/core/validation/validator-types.ts:146