/

Validation

Combine local node validity with Angular validators on the complete DfDataModel . Core maps validator node ids back to rendered nodes and applies the standard invalid wrapper state.

Local node stateForms and controls inside one custom node.
Graph validatorsPure Angular validators over nodes and connections.
Visual feedbackInvalid node ids receive the core wrapper style.

Node-Level Validation

Override the protected invalidState getter to combine local UI validity with invalidSignal() supplied by graph validators. Core reads the result from the custom component and applies .df-invalid to the editor node wrapper.

form-node.component.ts

    
      @Component({
  standalone: true,
  selector: 'app-form-node',
  imports: [ReactiveFormsModule],
  template: `
    <label>
      Task name
      <input [formControl]="name" />
    </label>
  `,
  host: {
    '(keydown.delete.stop)': '0',
    '(keydown.backspace.stop)': '0',
  },
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FormNodeComponent extends DrawFlowBaseNode {
  readonly name = new FormControl('', {
    nonNullable: true,
    validators: [Validators.required],
  });

  protected override get invalidState(): boolean {
    const localInvalid = this.name.touched && this.name.invalid;

    return this.invalidSignal() || localInvalid;
  }
}
    

Graph-Level Validation

Attach validators to the same non-nullable form control bound to ng-draw-flow . They receive the complete graph value and participate in normal Angular form status and errors.

editor.component.ts

    
      readonly form = new FormControl<DfDataModel>(initialModel, {
  nonNullable: true,
  validators: [
    dfCycleDetectionValidator(),
    dfIsolatedNodesValidator(),
  ],
});
    
ValidatorChecksNode ids
dfCycleDetectionValidator()Directed cycles in the connection structure.cycleNodes
dfIsolatedNodesValidator()Nodes absent from every source and target endpoint.isolatedNodes

Built-in Error Shapes

cycle-error.ts

    
      {
  hasCycle: boolean;
  cycleNodes: DfId[]; // array of nodeIds that form a cycle
}
    

isolated-nodes-error.ts

    
      {
  hasIsolatedNodes: boolean;
  isolatedNodes: DfId[] // array of nodeIds without connections
}
    

Custom Validators

Implement a standard Angular ValidatorFn and keep it pure. Return affected ids either as a top-level string array value or in a nested {nodeIds: string[]} object so the editor can highlight those nodes.

Do not mutate nodes or connections inside a validator. Return validation metadata and let application code decide how the graph should be repaired.

required-root.validator.ts

    
      export function requiredRootValidator(): ValidatorFn {
  return (control): ValidationErrors | null => {
    const model = control.value as DfDataModel;
    const roots = model.nodes.filter((node) => node.startNode === true);

    return roots.length === 1 ? null : {requiredRoot: {nodeIds: model.nodes.map(({id}) => id)}};
  };
}
    

The built-in cycle validator caches by connection structure. Isolated-node validation also reads the node list, so replacing graph arrays and objects remains the predictable update model.

Open the editor validation example