Nested fields
To add a little more structure to a complex form or to match the values of the form to your database, you can also nest your form fields in objects as deep as you like.
Schema definition
For example, in the schema below, the first and last name are grouped under the object with the key name.
import * as v from 'valibot';
const ContactSchema = v.object({
name: v.object({
first: v.pipe(v.string(), v.nonEmpty()),
last: v.pipe(v.string(), v.nonEmpty()),
}),
email: v.pipe(v.string(), v.email()),
message: v.pipe(v.string(), v.nonEmpty()),
});Path array
When creating a nested field, use an array with multiple elements as the path to refer to the nested field. The array represents the path through the nested structure.
<input
*formischField="['name', 'first'] of contactForm; let field"
[formischControl]="field"
type="text"
/>If you're using TypeScript, your editor will provide autocompletion for the path based on your schema structure.
Deep nesting
You can nest objects as deeply as needed. Simply extend the path array with additional keys:
import * as v from 'valibot';
const ProfileSchema = v.object({
user: v.object({
address: v.object({
street: v.string(),
city: v.string(),
country: v.string(),
}),
}),
});<!-- Access deeply nested field -->
<input
*formischField="['user', 'address', 'city'] of profileForm; let field"
[formischControl]="field"
type="text"
/>Type safety
The path array is fully type-safe. TypeScript will validate that each element in your path corresponds to a valid key in your schema structure, providing autocompletion and compile-time errors if you reference a non-existent path.
With strictTemplates enabled in the angularCompilerOptions of your tsconfig.json, this check also covers your templates: an invalid path in a *formischField expression fails the build, and the field store in the template context is typed with the value at that path.