zoedsoupe
How Phoenix.Component can handle events?
While searching and studying about live view I found this page of LiveComponent documentation, and reading more carefully about the “cost of a live component”, here: Phoenix.LiveComponent — Phoenix LiveView v1.2.5
Then it gives a not to do example, using a LiveComponent to wrap DOM events, like:
defmodule MyButton do
use Phoenix.LiveComponent
def render(assigns) do
~H"""
<button class="css-framework-class" phx-click="click">
<%= @text %>
</button>
"""
end
def handle_event("click", _, socket) do
_ = socket.assigns.on_click.()
{:noreply, socket}
end
end
So it preferable to use a functional component! Then, it was I did! I have this function component to wrap and style the native DOM button tag:
attr :style, :string, values: ~w(primary secondary), required: true
attr :submit, :boolean, default: false
attr :icon, :atom, required: false, default: nil
attr :class, :string, default: ""
attr :rest, :global, doc: ~s(used for phoenix events like "phx-click" and "phx-target")
slot :inner_block
def button(assigns) do
~H"""
<button
type={if @submit, do: "submit", else: "button"}
class={["btn", "btn-#{@style}", @class]}
{@rest}
>
<.icon :if={@icon} name={@icon} />
<.text :if={@style == "primary"} size="base" color="text-white-100">
<%= render_slot(@inner_block) %>
</.text>
<.text :if={@style != "primary"} size="base" color="text-blue-80">
<%= render_slot(@inner_block) %>
</.text>
</button>
"""
end
To be reusable in any phoenix template with a predefined style. My question is, how this function component can handle events, in this case, phx-click?
I used the button like this: https://github.com/peapescarte/pescarte-plataforma/blob/main/lib/pescarte_web/templates/landing_html/show.html.heex#L56-L58
However no event is trigged as can be seen in this little video:
Marked As Solved
benwilson512
Hey @zoedsoupe you’re absolutely right, it’s only very recently that Phoenix started using heex for controllers and I basically totally forgot it does that now!
So back to your question: Yea you can only do handle_event and phx-target stuff on components used in a live view. If you do need to use a functional component between both live and traditional views you could probably pass in myself: nil as an assign, but also the button won’t really work.
Also Liked
benwilson512
In short, it can’t. In order for a component to receive events it needs to be a stateful component that does use Phoenix.LiveComponent in its own module.
You generally also need to phx-target={@myself} to ensure that the events go to your component.
cmo
Function components do not handle events. Handle them in the parent liveview or livecomponent.
On a side note, this could be shorter:
<.text :if={@style == "primary"} size="base" color="text-white-100">
<%= render_slot(@inner_block) %>
</.text>
<.text :if={@style != "primary"} size="base" color="text-blue-80">
<%= render_slot(@inner_block) %>
</.text>
Could be:
<.text size="base" color={if @style == "primary", do: "text-white-100", else: "text-blue-80">
<%= render_slot(@inner_block) %>
</.text>
benwilson512
Not in the way you’re looking for that I see. That said if you read Components and HEEx — Phoenix v1.8.8 and the other docs it links to, you’ll notice that the word event never even appears. It’s only when you get to the live view docs do you start seeing events and handle_event.
Last Post!
benwilson512
Not in the way you’re looking for that I see. That said if you read Components and HEEx — Phoenix v1.8.8 and the other docs it links to, you’ll notice that the word event never even appears. It’s only when you get to the live view docs do you start seeing events and handle_event.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









