kkentzo
JS hooks do not receive the expected events from their corresponding live components
Hello!
I am facing an issue with JS hooks when there are multiple live components on the same live view.
More specifically:
- I have one live view that contains two live components
- each component is connected to a JS hook
- each JS hook subscribes to a
pingevent usinghandleEvent - on
update/2each live component sends apingevent to its hook usingpush_event
The problem is that both hooks receive one ping event that is sent from the second component only; the first component’s event never reaches the client.
I have set up a minimal example that demonstrates this problem in this repo.
Any insight on this behaviour? Am I doing something wrong?
Marked As Solved
chrismccord
This was a bug that has been fixed on master, but I also think there is some confusion here on how push_event works. Events are “global” for all hooks and can be pushed from any LiveView or component and read by any hook using handleEvent on the client. In this case, we have a diff producing two ping events . In your app what will be received is both hooks receive ping-a and ping-b events. It appears you are expecting pushed events to be isolated to their components, but that’s not the case. To get that kind of behavior you can namespace your events, ie:
|> push_event("ping-#{id}", ...)
this.handleEvent(`ping-${this.dataset.id}`, ...)
I just fixed the dup event keys being eaten, but your code needs to change to behave how you want. Make sense?
Also Liked
Matsa59
Effectively I observe the same behaviour that sounds like a bug.
Don’t use live view in live view for that simple case, instead you can :
# in the livecomponent
def update(%{id: id, counter: counter}, socket) do
send(self(), {:ping, id})
{:ok, socket |> assign(id: id, counter: counter)}
end
The send/2 will send a message to parent live view. So simply handle it like the following code:
# in the live view
def handle_info({:ping, id}, socket) do
{:noreply, push_event(socket, "ping", %{id: id})}
end
benwilson512
@kkentzo stateful live components are required to have unique DOM ids, but yours do not have any DOM ID at all: live-component-push-event-issue/lib/live_component_js_issue_web/live/counter_component.ex at master · kkentzo/live-component-push-event-issue · GitHub
kkentzo
@chrismccord: Makes full sense - yes, I am aware of the behaviour you are describing, it’s just that my trivial example was meant to demonstrate the “eaten” events.
Good to know that it’s now been fixed - many thanks!
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
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









