LiveVue
1.0
Nested Objects
Access nested form fields using
dot notation
paths. Perfect for forms with embedded objects like addresses, profiles, or settings.
What this example shows
How it works
1 Define an embedded schema or relation
Use embeds_one
or has_one/belongs_to to define nested objects. Each gets its own changeset and validation.
defmodule Address do
use Ecto.Schema
@derive LiveVue.Encoder
embedded_schema do
field :street, :string
field :city, :string
field :zip, :string
end
end
embeds_one :address, Address, on_replace: :update
2 Use cast_embed for validation
Call
cast_embed(:address)
to automatically validate nested fields. Errors are mapped to the correct nested paths.
def changeset(profile, attrs) do
profile
|> cast(attrs, [:name, :email])
|> validate_required([:name, :email])
|> cast_embed(:address, with: &Address.changeset/2)
end
3 Access nested fields with dot notation or chaining
Use
form.field("address.city")
or chain with .field().
Both have full TypeScript support for type-safe paths. Use `field[index]` to access nested array fields, eg `form.field("tags[0].name")`.
// Dot notation
const cityField = form.field("address.city")
// Or chain .field() calls
const addressField = form.field("address")
const cityField = addressField.field("city")
4 Bind inputs exactly like flat fields
Once you have a field reference, use it exactly like any other field.
The inputAttrs, errorMessage, and
isTouched
work identically.
<input v-bind="cityField.inputAttrs.value" type="text" />
<div v-if="cityField.errorMessage.value">
{{ cityField.errorMessage.value }}
</div>