Schema Validation Overview

Overview

Form-level schema validation enables cross-field validation rules that examine the entire form state. While field-level validators check individual fields, schema validators validate relationships between multiple fields.

When to Use Schema Validation

Schema validation excels at:

  • Password confirmation - Ensure two fields match
  • Date ranges - Validate end date is after start date
  • Conditional requirements - Complex business rules across fields
  • Data consistency - Ensure related fields are logically consistent

Available Approaches

Dynamic Forms supports two approaches to form-level validation:

ApproachBest ForWrapper Required
Angular SchemaAngular-only projects, full API accessNo (raw callback)
Standard SchemaReusing Zod/Valibot schemas, OpenAPIYes (standardSchema())

Angular Schema

Uses Angular's native schema APIs from signal forms. Best when:

  • Your project is Angular-only
  • You want zero additional dependencies
  • Validation logic is specific to this form
import { validateTree } from '@angular/forms/signals';

const config = {
  // Raw callback - no wrapper needed!
  schema: (path) => {
    validateTree(path, (ctx) => {
      const { password, confirmPassword } = ctx.value();
      if (password !== confirmPassword) {
        return [{ kind: 'passwordMismatch', fieldTree: ctx.fieldTreeOf(path).confirmPassword }];
      }
      return null;
    });
  },
  fields: [
    /* ... */
  ],
};

Standard Schema (Zod, Valibot, ArkType)

Uses the Standard Schema spec for cross-library compatibility. Best when:

  • You have existing Zod/Valibot schemas
  • You're reusing OpenAPI-generated schemas
  • You want the same validation on frontend and backend
import { z } from 'zod';
import { standardSchema } from '@ng-forge/dynamic-forms/schema';

const passwordSchema = z
  .object({
    password: z.string().min(8),
    confirmPassword: z.string(),
  })
  .refine((data) => data.password === data.confirmPassword, { message: 'Passwords must match', path: ['confirmPassword'] });

const config = {
  schema: standardSchema(passwordSchema),
  fields: [
    /* ... */
  ],
};

Comparison

FeatureAngular SchemaStandard Schema
DependenciesNone (Angular core)Schema library (Zod, etc.)
Type inferenceManualAutomatic from schema
Cross-platformNoYes (same schema in Node.js)
OpenAPI compatNoYes (via zod-openapi, etc.)
Learning curveFamiliar to Angular devsRequires schema library knowledge
Wrapper requiredNo (raw callback)Yes (standardSchema())

How It Works

  1. Define your schema (Angular or Standard Schema)
  2. Add it to your form configuration via the schema property
  3. The form validates against the schema on every change
  4. Schema errors are mapped to the appropriate fields

Next Steps