Skip to main content

FORM_NODE

FORM_NODE is the Angular injection token for the concrete [formNode] binding on the current host. Use it when a colocated directive or service needs that exact rendered control.

📐 Type

const FORM_NODE: InjectionToken<FormNodeBinding<AnyNode>>;

🔌 Same-host injection

import { FORM_NODE } from '@ngblocks/form-nodes';
import { Directive, inject } from '@angular/core';

@Directive({
selector: '[focusInvalidNode]',
host: { '(click)': 'focusWhenInvalid()' },
})
export class FocusInvalidNode {
private binding = inject(FORM_NODE, { self: true });

focusWhenInvalid() {
if (this.binding.node().invalid()) this.binding.focus();
}
}

Use { self: true } to avoid resolving an ancestor control. If the directive also supports hosts without [formNode], add optional: true; injection then returns null when absent.

🔌 Binding surface

MemberPurpose
node()Current bound node
errors()Errors visible to this binding
elementHost HTMLElement
injectorHost injector
focus(options?)Focuses this exact control
flush()Commits a pending control value
reset()Resets interaction and parsing state

Rebinding updates node() reactively. FORM_NODE represents a concrete binding, not merely a model node; use the node API when code does not care which rendered control is involved.

Most components can use #binding="formNode" with viewChild() instead of injection.

See [formNode] and Node API.

Custom components can inject this token during construction without changing output ordering. With immediate updates, valueChange, checkedChange, and touch template handlers see the updated node value or touched state. Configured debounce still applies. The token continues to resolve to the concrete directive instance. See custom output ordering.

For a reactive owning-form lookup, use useClosestFormState(). It wraps optional injection and model ownership resolution, and exposes the form's submission history through its result.