Liveview inputs_for phoenix 1.7 - how to use without the :let on the enclosing .form tag?

in the new 1.7 setup

it is recommended to use

<.form
  for={@form}

>

instead of

<.form
  :let={form}
  for={@changeset}
>

but then for the inputs_for the only example in the doc is in the old form

<.form
  :let={f}
  phx-change="change_name"
>
  <.inputs_for :let={f_nested} field={f[:nested]}>
    <.input type="text" field={f_nested[:name]} />
  </.inputs_for>
</.form>

how would you use it without the :let on the enclosing .form tag ?

There’s no alternative working around :let on <.inputs_for />.

It’s not. :clap:

All form-related components supports more use cases. There are no the only valid way or data to pass. Depending on use case you may for example use for={%{}} with as={:user}. The proper way depends not on phoenix version, but on your specific use case. My example was previously used in function form_for with first atom argument (like :user) and then passing an atom has been deprecated and the old way is still fully supported, but the new way requires using of as attribute. Please check the documentation for Phoenix.Component.form/1 and Phoenix.Component.inputs_for/1 components.

The for attribute can also be a map or an Ecto.Changeset. In such cases, a form will be created on the fly, and you can capture it using :let: (…)

However, such approach is discouraged in LiveView for two reasons:

  • LiveView can better optimize your code if you access the form fields using @form[:field] rather than through the let-variable form

  • Ecto changesets are meant to be single use. By never storing the changeset in the assign, you will be less tempted to use it across operations

Source: Using the for attribute

The term “discouraged” is not used in documentation to avoid usage of this option at all, as therefore it would be simply deprecated and removed in future releases, but it’s simply not recommended in some cases whereas in others it could be a “must have”.

form component is “top-level”, so it can easily take data from assings. @form is usually a changeset converted to Phoenix.HTML.Form. Since we have a @form we can reference to it when rendering input components. However the nested inputs can’t be generated by parent @form as then the html form would be incorrect i.e. the name attribute in nested inputs would act like it’s for @form and not nested structure. We just need something to reference to a nested form.

I had the same issue with this as posted here: <.inputs_for /> approach at odds with the new field-based change tracking?

Do you think the problem is now solved given the latest LV0.20.0 changelog:

Enhancements

  • Support change tracking on Access.get

Had no time to upgrade to 0.20.0 yet, but if you know someone tried this with the nested forms and it worked, would be a blessing.

No. The change in 0.20.0 was only around form[:test] and Access.get(form, [:test]) being supported the same.

<inputs_for /> would at least require further changes to how Phoenix.HTML.FormData implementations work to be optimized further for LV change tracking.

:cry: too bad

ok thanks

so when there is an inputs_for , you can keep the :let for the enclosing form
because there will be no LV optimisation or just for the fields not in inputs_for?

No. You still want to avoid :let with <.form>. There’s just no similar optimization for <.inputs_for />.