Skip to main content

NodeApi

The common API surface shared by all node kinds.

Import

import type { NodeApi } from '@ngblocks/form-nodes';

When to use it

Use when a helper needs only shared state and operations. This is the API object contract; use AnyNode for the node itself and access its $api.

Declaration

type NodeApi = {
nodeType(): NodeType;
onValueChange(callback: (value: any, node: AnyNode) => void, options?: {
injector?: Injector;
debounce?: number;
}): () => void;
form: Signal<AnyNode | null>;
root: Signal<AnyNode>;
parent: Signal<AnyNode | null>;
path: Signal<readonly string[]>;
value: NodeValueSignal<any>;
asReadonly(): Signal<any>;
keyInParent: Signal<string | number | null>;
set(value: any): void;
update(updater: (value: any) => any): void;
patch(value: any): void;
reset(...args: [
] | [
value: any
]): void;
resetToInitial(): void;
validationStatus: Signal<'valid' | 'invalid' | 'unknown'>;
valid: Signal<boolean>;
invalid: Signal<boolean>;
errors: NodeErrorsSignal<AnyNode>;
allErrors: Signal<readonly ValidationErrorWithTargetNode<AnyNode>[]>;
getError<TKind extends keyof ValidationErrorMap | (string & {})>(kind: TKind): (ValidationErrorWithTargetNode<AnyNode> & {
readonly kind: TKind;
}) | undefined;
hasError(kind: keyof ValidationErrorMap | (string & {})): boolean;
hasValidator(validator: (context: any) => unknown, options?: {
resolve?: boolean;
}): boolean;
required: Signal<boolean>;
pending: Signal<boolean>;
submitting: Signal<boolean>;
debouncing: Signal<boolean>;
flush(): void;
focus(options?: FocusOptions): void;
touched: Signal<boolean>;
untouched: Signal<boolean>;
markAsTouched(options?: {
skipDescendants?: boolean;
}): void;
markAsUntouched(): void;
dirty: Signal<boolean>;
pristine: Signal<boolean>;
markAsDirty(): void;
markAsPristine(): void;
disabled: Signal<boolean>;
disabledReasons: Signal<readonly DisabledReason[]>;
enabled: Signal<boolean>;
disable(message?: string): void;
enable(): void;
readonly: Signal<boolean>;
writable: Signal<boolean>;
markAsReadonly(): void;
markAsWritable(): void;
hidden: Signal<boolean>;
visible: Signal<boolean>;
hide(): void;
show(): void;
};

Declared members

The declaration above also includes inherited contracts and overloads where applicable.

MemberMeaning
nodeTypeReturns the concrete primitive represented by this node.
onValueChangeObserves future exposed value changes synchronously, respecting equality and debounce. Returns an idempotent cancellation function. An explicit injector or the registration context owns the listener; node injector destruction also ends it. DI-free use is supported.
formNearest explicit form() containing this node, or null when no form workflow owns it.
rootComplete root node containing this node. A root node returns itself.
parentImmediate structural parent of this node, or null when it is a root or has been detached.
pathProperty and array-index segments from the complete root to this node. Root nodes use []. Array indexes are represented as strings.
valueCurrent committed value represented by this node. Reading it participates in signal tracking.
asReadonlyReturns a stable, live readonly signal of the exposed value, with no node operations. Preserves configured equality and committed-value reads; pending control input remains pending. This does not mark the node readonly or prevent deep mutation of object values. The node and its $api return the same signal, and the method is safe to extract.
keyInParentProperty or array index under which this node is stored, or null when it is a root node.
setAssigns a complete committed value immediately without marking the node dirty.
updateComputes and assigns a complete committed value without marking the node dirty.
patchUpdates supplied object branches or replaces complete array/field values without marking the node dirty.
resetClears interaction state and pending control input throughout the reset scope, optionally assigning a new complete value first.
resetToInitialRestores captured initial values, cancels buffered input, and clears subtree dirty/touched state. Object nodes keep their current schema; arrays restore their initial values, count, and order. Programmatic writes do not redefine the baseline. Current validators and availability remain. Supported data containers are copied; opaque instances and accessor state retain references. This does not emit control-originated value outputs. See concrete node APIs for full details.
validationStatusAggregated validation phase for this node and its subtree.
validWhether this node and its descendants have completed validation without errors.
invalidWhether this node or any descendant currently contributes a validation error.
errorsValidation errors belonging directly to this node by default. Pass { descendants: true } to include descendants, exactly as allErrors().
allErrorsValidation errors from this node and its complete subtree in structural order.
getErrorReturns the first error belonging directly to this node and matching kind. Suggests registered error kinds while accepting any custom string.
hasErrorWhether this node's own errors include the kind; does not search descendants. Suggests registered error kinds while accepting any custom string.
hasValidatorWhether this exact validator is directly registered, or resolved when resolve is true.
requiredWhether active validation metadata currently marks this node as required.
pendingWhether asynchronous validation is active on this node or any descendant.
submittingWhether this node is a form running its submission action, or has an ancestor form that is currently running one.
debouncingWhether a control-originated value is awaiting commit on this node or any descendant.
flushImmediately commits pending control-originated values on this node and its flush scope.
focusFocuses the first control bound to this node or its descendants, when one exists.
touchedWhether this node or any descendant has been marked touched.
untouchedLogical inverse of touched().
markAsTouchedMarks this node and, by default, its interactive descendants as touched and commits their pending control values for every debounce strategy.
markAsUntouchedClears this node's own touched marker without changing descendant markers or values. An interactive touched descendant can keep an aggregate touched() true. Use reset() to clear interaction state throughout the subtree.
dirtyWhether this node currently reports user-modified state.
pristineLogical inverse of dirty().
markAsDirtyMarks this node's own state dirty, making dirty() true and pristine() false while it is interactive.
markAsPristineClears this node's own dirty state. pristine() becomes true and dirty() false only when no contributing descendant remains dirty.
disabledWhether this node is effectively disabled by a local or inherited reason.
disabledReasonsParent reasons followed by the active reasons originating on this node.
enabledLogical inverse of disabled().
disableDisables this node, optionally recording a user-facing reason. Sets disabled() to true and enabled() to false on this node and its effective subtree.
enableClears local disabled state, including a static initial disabled option. Continuing reactive conditions and inherited reasons remain effective, so enabled() may stay false.
readonlyWhether this node is effectively readonly through local configuration or an ancestor.
writableLogical inverse of readonly().
markAsReadonlyMarks this node and its subtree readonly, making readonly() true and writable() false.
markAsWritableClears local readonly state, including a static initial readonly option. Reactive conditions and ancestor readonly state can still prevent the node from becoming writable.
hiddenWhether this node is effectively hidden through local configuration or an ancestor.
visibleLogical inverse of hidden().
hideHides this node and its subtree, making hidden() true and visible() false.
showClears local hidden state, including a static initial hidden option. Reactive conditions and ancestor hidden state can still keep the node hidden.