FieldApi
State, value views, navigation, and operations available on a field node.
Import
import type { FieldApi } from '@ngblocks/form-nodes';
When to use it
Use for helpers that operate on field state and actions without accepting a node declaration. A field's $api additionally has the callable signal contract described by CallableNodeApi.
Declaration
type FieldApi<TValue, TParent extends AnyNode = AnyNode> = {
nodeType(): 'field';
onValueChange(callback: (value: TValue, node: FieldNode<TValue, TParent>) => void, options?: {
injector?: Injector;
debounce?: number;
}): () => void;
form: Signal<NearestForm<TParent> | null>;
root: Signal<IsUnknownNode<TParent> extends true ? NavigationRoot : RootNode<TParent>>;
parent: Signal<TParent | null>;
path: Signal<readonly string[]>;
keyInParent: Signal<NodeKeyInParent<TParent>>;
value: NodeValueSignal<TValue, TValue>;
asReadonly(): Signal<TValue>;
set(value: TValue): void;
update(updater: (value: TValue) => TValue): void;
debouncing: Signal<boolean>;
flush(): void;
focus(options?: FocusOptions): void;
patch(value: TValue): void;
reset(...args: [
] | [
value: TValue
]): void;
resetToInitial(): void;
validators: Signal<Validators<TValue>> & {
(options: {
resolve?: boolean;
}): Validators<TValue>;
};
setValidators(validators: ValidatorSource<TValue, FieldNode<TValue>>): void;
errors: NodeErrorsSignal<FieldNode<TValue, TParent>>;
allErrors: Signal<readonly ValidationErrorWithTargetNode<AnyNode>[]>;
valid: Signal<boolean>;
invalid: Signal<boolean>;
getError<TKind extends keyof ValidationErrorMap>(kind: TKind): (ValidationErrorWithTargetNode<FieldNode<TValue, TParent>> & ValidationErrorMap[TKind]) | undefined;
getError<TKind extends keyof ValidationErrorMap | (string & {})>(kind: TKind): (ValidationErrorWithTargetNode<FieldNode<TValue, TParent>> & CustomValidationError<TKind>) | undefined;
hasError(kind: keyof ValidationErrorMap | (string & {})): boolean;
hasValidator(validator: (context: any) => unknown, options?: {
resolve?: boolean;
}): boolean;
min: Signal<NonNullable<TValue> | null>;
max: Signal<NonNullable<TValue> | null>;
minLength: Signal<number | null>;
maxLength: Signal<number | null>;
pattern: Signal<readonly RegExp[]>;
required: Signal<boolean>;
pending: Signal<boolean>;
submitting: Signal<boolean>;
validationStatus: Signal<ValidationStatus>;
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;
};
Type parameters
| Parameter | Constraint | Default |
|---|---|---|
TValue | Unconstrained | Required |
TParent | AnyNode | AnyNode |
Declared members
The declaration above also includes inherited contracts and overloads where applicable.
| Member | Meaning |
|---|---|
nodeType | Returns the concrete primitive represented by this node. |
onValueChange | Subscribes to future exposed value changes and returns an idempotent cancellation function. Runs untracked, respects equality and control debounce, and skips initial values. Multiple listeners coexist with the construction callback; subscriptions are not cloned. The explicit injector, otherwise the registration context, owns the listener. The node's current injector also ends the subscription on destruction and acts as the fallback owner. Binding and ancestor ownership follow the node when it is rebound or detached. Without an injector, observation still works and can be canceled manually. A positive debounce delays only this callback until that many milliseconds without another change. Omitted or zero stays synchronous. Cancellation drops pending delivery. Node values, validation, and interaction state are unaffected by the subscription delay. |
form | Nearest explicit form() containing this field, or null when no form workflow owns it. A nested explicit form is the workflow owner instead of the complete structural root. |
root | Complete structural root containing this field. A standalone or detached field returns itself. Use this signal when traversal must cross nested form workflow boundaries. |
parent | Immediate structural parent of this field, or null when it is a root or has been detached. |
path | Property and array-index segments from the complete root to this field. Root fields use []. |
keyInParent | Property or array index under which this field is stored, or null when it is a root field. |
value | Exposed field value. The equal option may retain an earlier equivalent value independently of the latest committed write used by controls and reset. |
asReadonly | Returns 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. |
set | Assigns a committed value immediately without marking the field dirty. |
update | Computes and sets a complete value from the current exposed value without marking the field dirty. |
debouncing | Whether a control-originated value is waiting to be committed by this field's numeric, blur-based, or asynchronous debounce. Programmatic writes do not activate this signal. |
flush | Immediately commits the pending value.control(), ending its configured debounce. Has no observable effect when no control update is pending. |
focus | Focuses the first [formNode] control currently bound to this field in DOM order. |
patch | Assigns a committed value like set(). Available through $api for generic infrastructure; ordinary field updates use set(). |
reset | Clears touched and dirty state and cancels pending control input. Passing a value also replaces internally committed value; omitting it preserves that value even when equal retains an older exposed value. Controls reset to the internally committed value. |
resetToInitial | Restores the field's captured initial value and resets its interaction state. |
validators | Current normalized validators assigned directly to this field, in declaration order. |
setValidators | Replaces this field's validators and immediately validates the current exposed value. |
errors | A signal containing the validation errors of this field itself. |
allErrors | A signal containing the validation errors of this field and its descendants. Fields have no descendants, so this contains the same errors as errors(). |
valid | Whether this field has completed validation without errors. False while validity is unknown. |
invalid | Whether this field currently has at least one validation error. |
getError | Returns the first validation error of this field matching kind. Suggests registered error kinds while accepting any custom string. |
hasError | Whether this node's own errors contain the given kind. Does not search descendants. Suggests registered error kinds while accepting any custom string. |
hasValidator | Whether the same validator function is directly registered on this node, including async validators. By default, does not run validators. Set resolve to true to inspect resolved leaf references. |
min | Strictest minimum value contributed by active numeric or date validators, or null when absent. |
max | Strictest maximum value contributed by active numeric or date validators, or null when absent. |
minLength | Strictest minimum length contributed by active length validators, or null when absent. |
maxLength | Strictest maximum length contributed by active length validators, or null when absent. |
pattern | Every regular expression contributed by the field's active pattern validators. |
required | Whether an active required validator currently marks this field as required. |
pending | Whether this field has one or more active asynchronous validation operations. |
submitting | Whether an ancestor form is currently running its submission action. |
validationStatus | Current validation phase: 'valid', 'invalid', or 'unknown'. |
touched | Whether this field has been marked touched. |
untouched | Logical inverse of touched(). |
markAsTouched | Marks this field as touched and commits its pending control value for every debounce strategy while it is interactive. |
markAsUntouched | Clears stored touched state, making touched() false and untouched() true. |
dirty | Whether this field currently reports user-modified state. |
pristine | Logical inverse of dirty(). |
markAsDirty | Marks this field as dirty, making dirty() true and pristine() false while it is interactive. |
markAsPristine | Clears stored dirty state, making dirty() false and pristine() true. |
disabled | Whether this field is effectively disabled by its own state or an ancestor reason. |
disabledReasons | Active inherited and local causes of this field's disabled state. |
enabled | Logical inverse of disabled(). |
disable | Disables this field, optionally recording a user-facing reason. Sets disabled() to true and enabled() to false. |
enable | Clears local disabled state, including a static initial disabled option. Continuing reactive conditions and inherited reasons remain effective, so enabled() may stay false. |
readonly | Whether this field is effectively readonly through its own state or an ancestor. |
writable | Logical inverse of readonly(). |
markAsReadonly | Marks this field readonly, making readonly() true and writable() false. |
markAsWritable | Clears local readonly state, including a static initial readonly option. Reactive conditions and ancestor readonly state can still prevent the node from becoming writable. |
hidden | Whether this field is effectively hidden through its own state or an ancestor. |
visible | Logical inverse of hidden(). |
hide | Hides this field, making hidden() true and visible() false without changing its value. |
show | Clears local hidden state, including a static initial hidden option. Reactive conditions and ancestor hidden state can still keep the node hidden. |