I want to pass a whole item as a parameter to an event handler? The use-case I want to support is having a select input with options of multiple types.
Right now I’m forced to do this. But I want to support items of different types that may have the same table-local id, or might not have an id field at all.
<%= for item <- @items do %>
<button phx-click="select_item" phx-target={@myself} phx-value-id={item.id}>
<%= render_slot(@option, item) %>
</button>
<% end %>
I want to be able to support this below, but I’m getting a protocol Phoenix.HTML.Safe not implemented for %{description: "", id: 1, title: ""} of type Map. error.
<%= for item <- @items do %>
<button phx-click="select_item" phx-target={@myself} phx-value-item={item}>
<%= render_slot(@option, item) %>
</button>
<% end %>
As you’ve discovered, you can only pass fairly basic data structures in as values. You have a couple of options:
Generate a lookup server-side (e.g. a map) which links a simple key you can pass to phx-target... and use that in the event-handler to lookup the actual data item. The advantage of this is it minimises encoding/decoding, plus the size of the payload going back and forth to the browser.
I’d probably opt for 1 if your client doesn’t need to know anything about the data (i.e. you’re not envisaging writing any javascript hooks to decode the value).