I’m stumped. I have a LiveView form tied to a Changeset (rather than a schema) like so:
~H"""
<.form as={:form} for={@changeset} :let={f} phx-change="validate" phx-submit="save">
<.input field={f[:email]} />
</.form>
"""
I can see errors collecting into my changeset on validate. What’s the best pattern for showing an error from the changeset? I see reference to phx-feedback-for
and an <.error>
helper, but something like this:
<div phx-feedback-for={:email}>
<.input field={f[:email]} />
<.error :for={msg <- @changeset.errors}><%%= msg %></.error>
</div>
leaves me with an Parse error ... expected attribute name
.
Thank you in advance.
An update in case it’s helpful. I can certainly pattern match like:
<.error :for={{:email, {error_msg, _}} <- @changeset.errors}>
<%= error_msg %>
</.error>
However, I suspect I’m still doing something wrong. The docs for phx-feedback-for
seem to indicate that wrapping my error with a field value like :email
would filter errors just for that field. But I have to explicitly match on :email
to avoid multiple error messages appearing in one spot. It just feels a bit cumbersome or redundant, but it works.
1 Like
That’s because the input
component from the generated core components uses the field scoped @errors
rather than the entire form’s @changeset.errors
. It then uses these input field specific errors to render error
components within the input
component itself.
def input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do
assigns
|> assign(field: nil, id: assigns.id || field.id)
|> assign(:errors, Enum.map(field.errors, &translate_error(&1)))
...
end
1 Like
That makes sense. Now I can see where @errors is coming from — assigns(:errors ...)
in the core component. Thank you.