4. Add nesting and reactive state
Group related fields with shorthand objects. Use an explicit group() when that branch needs its
own configuration.
The validators from the previous step are omitted here so the nested structure remains easy to scan. They can stay on the same fields in the complete application without changing how nesting works.
readonly useShippingAddress = signal(true);
form = form({
name: field(''),
age: field<number>(null),
email: field(''),
shippingAddress: {
street: field(''),
city: field(''),
postalCode: field(''),
},
billingAddress: group({
street: field(''),
city: field(''),
postalCode: field(''),
}, {
disabled: () => this.useShippingAddress()
? 'Using the shipping address for billing.'
: false,
}),
});
The billing branch reacts to useShippingAddress() automatically. While disabled:
- Its values remain readable and writable.
- Its errors and pending state are suppressed.
- It does not make the root invalid.
disabledReasons()retains the message and source node.
Nested values and access remain direct:
this.form.shippingAddress.city(); // ''
this.form.billingAddress.disabled();
this.form.patch({
shippingAddress: {
city: 'Zurich',
},
});
🔗 Related guides and reference​
- Interaction and availability documents touched, dirty, disabled, readonly, hidden, propagation, and suppression behavior.
- Tree navigation and API access explains direct children, paths, parents, roots, and name collisions.
- Values and state covers nested updates and aggregate state.
group()reference documents nested shorthand and explicit group options.
Continue with Step 5: Manage a dynamic array.