Interface

CustomFnConfig

@ng-forge/dynamic-forms

Signal forms adapter configuration for advanced form behavior.

Provides configuration options for signal forms integration including legacy migration, custom functions, and custom validators.

Signature

interface CustomFnConfig<
  TFormValue extends Record<string, unknown> = Record<string, unknown>
>

Type Parameters

NameConstraintDefaultDescription
TFormValueRecord<string, unknown>Record<string, unknown>-

Properties

NameTypeDescription
customFunctions ?Record<string, CustomFunction<TFormValue>>

Custom evaluation functions for conditional expressions.

Used for: when/readonly/disabled logic Return type: any value (typically boolean)

derivations ?Record<string, CustomFunction<TFormValue>>

Custom derivation functions for value derivation logic.

These functions compute derived values and are called when a DerivationLogicConfig references them by functionName.

Derivation functions: - Receive an EvaluationContext with access to formValue - Return the value to set on the target field - Are called reactively when dependencies change

Use derivation functions for complex mappings or logic that can't be easily expressed as a JavaScript expression.

asyncDerivations ?Record<string, AsyncDerivationFunction<TFormValue>>

Async derivation functions for asynchronous value derivation logic.

These functions perform asynchronous operations (service calls, complex pipelines) and return the derived value via a Promise or Observable. They are called when a DerivationLogicConfig references them by asyncFunctionName.

Async derivation functions: - Receive an EvaluationContext with access to formValue - Return a Promise or Observable of the value to set on the target field - Handle their own I/O (no HttpClient provided — use injected services) - Require explicit dependsOn to avoid triggering on every form change

asyncConditions ?Record<string, AsyncConditionFunction<TFormValue>>

Async condition functions for asynchronous field state logic.

These functions perform asynchronous operations and return a boolean indicating whether the condition is met. They are referenced by asyncFunctionName in AsyncCondition expressions.

Async condition functions: - Receive an EvaluationContext with access to formValue - Return a Promise or Observable of boolean - Handle their own I/O (use injected services)

validators ?Record<string, CustomValidator>

Custom validators using Angular's public FieldContext API

(ctx, params?) => ValidationError | ValidationError[] | null

Validators receive FieldContext which provides access to: - Current field value: ctx.value() - Field state: ctx.state (errors, touched, dirty, etc.) - Other field values: ctx.valueOf(path) - public API! - Other field states: ctx.stateOf(path) - Parameters from JSON configuration

Return Types: - Single error: { kind: 'errorKind' } for field-level validation - Multiple errors: [{ kind: 'error1' }, { kind: 'error2' }] for cross-field validation - No error: null when validation passes

asyncValidators ?Record<string, AsyncCustomValidator<unknown, unknown, unknown>>

Async custom validators using Angular's resource-based validateAsync() API

Angular's validateAsync uses the resource API for async validation. Validators must provide params, factory, onSuccess, and optional onError callbacks.

Structure: - params: Function that computes params from field context - factory: Function that creates ResourceRef from params signal - onSuccess: Maps resource result to validation errors - onError: Optional handler for resource errors

Use Cases: - Database lookups via services with resource API - Complex async business logic with Angular resources

Note: For HTTP validation, prefer httpValidators which provides a simpler API specifically designed for HTTP requests.

httpValidators ?Record<string, HttpCustomValidator<unknown, unknown>>

HTTP validators using Angular's validateHttp() API.

For function-based HTTP validation with automatic request cancellation. Prefer declarative HTTP validators (type: 'http' with http + responseMapping) for fully JSON-serializable validation when possible.

Examples

customFnConfig: {
  customFunctions: {
    isAdult: (context) => context.age >= 18,
    formatCurrency: (context) => new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD'
    }).format(context.value)
  },
  derivations: {
    getCurrencyForCountry: (context) => {
      const countryToCurrency: Record<string, string> = {
        'USA': 'USD', 'Germany': 'EUR', 'UK': 'GBP'
      };
      return countryToCurrency[context.formValue.country as string] ?? 'USD';
    }
  },
  simpleValidators: {
    noSpaces: (value) => {
      return typeof value === 'string' && value.includes(' ')
        ? { kind: 'noSpaces', message: 'Spaces not allowed' }
        : null;
    }
  },
  contextValidators: {
    lessThanField: (ctx, params) => {
      const value = ctx.value();
      const otherField = params?.field as string;
      const otherValue = ctx.root()[otherField]?.value();
      if (otherValue !== undefined && value >= otherValue) {
        return { kind: 'notLessThan', message: `Must be less than ${otherField}` };
      }
      return null;
    }
  }
}