Calling `show_modal` JS function from LiveView `handle_event`


I was wondering if it’s possible to call a JS function (show_modal from core_components.ex in this case) from a handle_event function.

Let’s say I have this socket event handler called to set item_to_edit:

  def handle_event("edit", %{"id" => id}, socket) do
    item = Items.get_item!(id)
    {:noreply, assign(socket, :item_to_edit, item)}

I’d like to open a modal that contains the item form.

Currently I can call open_modal directly in the HEEX template with phx-click, but it would open the modal before the item is loaded, showing blank, and suddenly shows everthing - I figure the UX will probably be worse with slow connections. Ideally I’d like to open the modal after the assign is set.

Is this possible?


Hi, @byw ! :wave:

Looks like what you want it to push_event/3 from the server, catch it in the client with a hook or just event listener and execute JS command with liveSocket.execJS.

See more in details in the section “Handling server-pushed events”


The default generates something like this:

  :if={@live_action in [:new, :edit]}

I guess it should work if in the aforementioned :if condition you set the assign variable (in the above example being @live_action) and the corresponding value (in the above example being :new, :edit) to what you desire. I believe that this will delay the displaying of the modal until the assign has the proper value.
I have not tested this solution, though.


Ah, I was creating a live view from scratch. The generator seems to produce a lot of idiomatic code for me, looks great for learning. Thanks!

1 Like