Hi everyone.
On this github issue Provide a unified mechanism to message the parent/child · Issue #1597 · phoenixframework/phoenix_live_view · GitHub, @chrismccord suggests that we can use “callback” attributes for a live view component to handle messages that needs to be sent to a parent.
For example, let’s say we have a live component that needs to send a message back to a parent live component/liveview, something like this:
defmodule MyLiveComponent do
use CoreWeb, :live_component
attr :id, :string, required: true
attr :on_complete, :any, required: true
def live_render(assigns), do: ~H"<.live_component module={__MODULE__} {assigns} />"
def update(assigns, socket), do: ...
def handle_event("some_event", _, socket) do
%{on_complete: on_complete} = socket.assigns
on_complete.(some_value)
{:noreply, socket}
end
def render(assigns), do: ...
end
With this, I can now instantiate this component like this:
<MyLiveComponent.live_render
id="id"
on_complete={fn value -> send(self(), {:value, value}) end}
/>
Or like this:
<MyLiveComponent.live_render
id="id"
on_complete={fn value -> send_update(__MODULE__, id: @id, action: :value, result: value) end}
/>
This works great and make the component very flexible. But it at the same time it is not very clear for the end user what exactly :on_complete
takes since there is no way to define a function definition for it right now.
For a small component this is fine since I can just check the handle_event
call and understand what the function takes, but if my component is more complex, or if I’m making a component for a library, that can be a big issue.
I thought about creating an issue in liveview’s github about this, but first I guess it would make more sense to discuss with the community if everyone thinks this would be a good idea or if there is a good workaround.
Also, it would be great to get some suggestion on how a function definition would work in this case.
An obvious one would be to have something like this:
attr :on_complete, {:function, 3}
attr :on_complete, {:function, [:string, :integer, :any]}
attr :on_complete, {:function, [arg_name_1: :string, arg_name_2: :integer, arg_name_3: :any]}
Any suggestions are welcome.