I have a situation where one stateful LiveComponent is nested inside a parent stateful LiveComponent. I want the child innermost component to handle its own events. But the best I can do is get its parent handle_event/3
to be called. So my question is can LiveComponents which are stateful (have the :id assign) nest to arbitrary levels and still handle their own events or is this not supported?
Here is the code in question with just the relevant parts for illustration:
defmodule AppWeb.Live.AppLive do
def render(assigns) do
~L"""
<div>
<%= live_component @socket, AppWeb.Live.Components.Home, id: :home %>
</div>
"""
end
end
defmodule AppWeb.Live.Components.Home do
def render(assigns) do
~L"""
<div>
<h1>Home</h1>
<%= live_component @socket, AppWeb.Live.Components.TextInput, id: :text_input %>
</div>
"""
end
end
defmodule AppWeb.Live.Components.TextInput do
def render(assigns) do
~L"""
<div>
<%= f = form_for @input_changeset, "#",
phx_change: :validate,
phx_submit: :save,
phx_target: @myself %>
<%= textarea f, :description %>
<%= submit "Save" %>
</form>
</div>
"""
end
def handle_event("validate", params, socket) do
Logger.info("validate called")
{:noreply, socket}
end
end
I’ve tried every way I know but I can’t get handle_event/3
to be called on the innermost child component. If I move it to the parent, it gets called. So am I attempting something that is not supported?
Please try master. There was a bug in my query selector for @myself
, where we’d sometimes target the wrong component for a parent with the same internal component ID.
4 Likes
Ah, that addressed my problem too, thx for the post! Is there a roadmap publicly available to LiveView 1.0?
Thanks @chrismccord, I will try this out today if I can. I tried switching to master in my existing project and got some errors that I couldn’t easily resolve. Today I’ll start a fresh project and import the code in question and see if I can get that to work. I’ll let you know how it goes…thanks again!
@chrismccord or anyone else who knows…could you point me to how to install from master? I tried just updating the deps in mix.ex and running mix deps.get but I get the following:
Dependencies have diverged:
* phoenix_pubsub (https://github.com/phoenixframework/phoenix_pubsub)
the dependency phoenix_pubsub in mix.exs is overriding a child dependency:
> In mix.exs:
{:phoenix_pubsub, [env: :prod, git: "https://github.com/phoenixframework/phoenix_pubsub"]}
> In deps/phoenix/mix.exs:
{:phoenix_pubsub, "~> 2.0-dev", [env: :prod, git: "https://github.com/phoenixframework/phoenix_pubsub.git"]}
Ensure they match or specify one of the above in your deps and set "override: true"
* phoenix_html (https://github.com/phoenixframework/phoenix_html)
the dependency phoenix_html in mix.exs is overriding a child dependency:
> In mix.exs:
{:phoenix_html, [env: :prod, git: "https://github.com/phoenixframework/phoenix_html"]}
> In deps/phoenix/mix.exs:
{:phoenix_html, "~> 2.13", [env: :prod, repo: "hexpm", hex: "phoenix_html", optional: true]}
Ensure they match or specify one of the above in your deps and set "override: true"
* phoenix (https://github.com/phoenixframework/phoenix)
the dependency phoenix in mix.exs is overriding a child dependency:
> In mix.exs:
{:phoenix, [env: :prod, git: "https://github.com/phoenixframework/phoenix"]}
> In deps/phoenix_live_reload/mix.exs:
{:phoenix, "~> 1.4", [only: :dev, env: :prod, repo: "hexpm", hex: "phoenix"]}
Ensure they match or specify one of the above in your deps and set "override: true"
** (Mix) Can't continue due to errors on dependencies
I’m probably doing this wrong. What’s the correct way to install from master for all the deps needed for this?
Here are the instructions:
# If you want the latest features, install from GitHub:
def deps do
[
{:phoenix_live_view, github: "phoenixframework/phoenix_live_view"},
{:floki, ">= 0.0.0", only: :test}
]
@sfusato thanks! I was able to get master installed and can confirm that it works as expected now.