Hi,
I’m trying to build a LiveComponent, which provides a drop-down where users can select different items.
I could use some help getting update() to run so that I can assign some data.
Following the tutorial at Fly.io, it looks like update() only needs params and socket?
How should I craft my code to assign data when the component loads?
In my attempt I get this error:
# Returns CompileError: cannot declare attributes for function update/2.
# Components must be functions with arity 1
This is how I use the component from the main view:
<.live_component
module={ComponentSelector}
name="Camera"
context="camera"
coming_from="dsp"
form={@form}
list_for_selector={Cameras.list_approved_cameras()}
id="dsp"
The LiveComponent itself:
defmodule MyAppWeb.Components.ComponentSelector do
use MyAppWeb, :live_component
import Phoenix.HTML.Form
alias MyApp.Cameras
attr :name, :string, required: true
attr :list_for_selector, :list, required: true
attr :form, :map, required: true
attr :context, :string, required: true
# Returns CompileError: cannot declare attributes for function update/2.
# Components must be functions with arity 1
def update(_params, socket) do
IO.puts("\n\n ComponentSelector update\n\n ")
# ^ This is never called
{:ok, assign(socket, :selected_components, [])}
end
def render(assigns) do
key = @name
~H"""
<div class="component-selector">
<h2><%= @name %></h2>
<select phx-change="component_selected_from_dropdown" name="component_selected"
phx-target={@myself} >
<%= options_for_select(@list_for_selector, 0) %>
</select>
<button
form="ignore-me"
phx-click="add_component"
phx-target={@myself}
value={"#{String.downcase(@name)}" }
class="ml-2"
>
Add
</button>
</div>
"""
end
def handle_event("add_component", %{"value" => context}, socket) do
component_id = socket.assigns.component_id_selected
if component_id == nil do
{:noreply, socket}
else
IO.puts "to be implemented"
component =
case context do
"display" ->
display = Components.get_display!(component_id)
"camera" ->
Cameras.get_camera!(component_id)
end
components = socket.assigns.selected_components
socket = assign(socket, :selected_components, [component | components])
{:noreply, socket}
end