Hello,
I’m getting a little stuck on a LiveView issue and wonder if some folks had some ideas/feedback. Essentially, I have a live_component that renders as a realtimesearch input field. I need to have this realtime functionality on one-to-many nested input field.
Oversimplified, but imagine a list has embedded items and each item must have a single category from a few thousand categories.
<.form :let={f} id="list" for={@changeset} phx-submit="save" phx-change="validate">
<%= inputs_for f, :items, fn item -> %>
<.live_component
id={item.id <> "_category"}
module={LiveSearchInput}
form={item}
user_return_to={@user_return_to}
/>
<.link phx-click="remove_category" phx-value-item_index={item.index} class="text-red-500">
<% end %>
<.button phx-click="add-item" id="add-item" type="button"><%= gettext("Add") %></.button>
</.form>
When I tried to do this, I get the following error about using inside of an enumerable:
** (ArgumentError) cannot convert component MyApp.Components.LiveSearchInput with id ""list_items_0_category"" to HTML.
A component must always be returned directly as part of a LiveView template.
For example, this is not allowed:
<%= content_category :div do %>
<.live_component module={SomeComponent} id="myid" />
<% end %>
That's because the component is inside `content_category`. However, this works:
<div>
<.live_component module={SomeComponent} id="myid" />
</div>
Components are also allowed inside Elixir's special forms, such as
`if`, `for`, `case`, and friends.
<%= for item <- items do %>
<.live_component module={SomeComponent} id={item} />
<% end %>
However, using other module functions such as `Enum`, will not work:
<%= Enum.map(items, fn item -> %>
<.live_component module={SomeComponent} id={item} />
<% end %>
Are there any workarounds or general approaches I’m overlooking?
For context, I’m modeling my real-time behavior from this example from Chris McCord.