Live View JS hook not executing when I push_event

I have registered a hook like this in my app.js

let hooks = {};

hooks.ClickButton = {
  mounted() {
    this.handleEvent("click-button", (data) => {
      const button = document.getElementById(data.id);
      console.log("click-button");
      console.log(data);
      console.log(button);
      if (button) {
        button.click();
      }
    });
  }
};

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {
    hooks: hooks,
    params: {_csrf_token: csrfToken}
})


// Show progress bar on live navigation and form submits
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
window.addEventListener("phx:page-loading-start", _info => topbar.show(300))
window.addEventListener("phx:page-loading-stop", _info => topbar.hide())

// connect if there are any LiveViews on the page
liveSocket.enableDebug()
liveSocket.connect()
window.liveSocket = liveSocket

In my live view I am pushing the event like this:

  defp maybe_push_ics_open_click(socket) do
    if get_in(socket.assigns, [:conversion, :ics]) do
      dbg("pushing add to calendar click. connected: #{connected?(socket)}")
      push_event(socket, "click-button", %{id: "add-to-calendar-button"})
    else
      socket
    end
  end

I can see the dbg coming on the backend:

"pushing add to calendar click. connected: true"

But the only thing I see in my browser console is the mount event. I would have at least expected to see the the “click-button” event was received by the browser. Not sure how to debug this.

I’m guessing that the result from maybe_push_ics_open_click/1 isn’t being passed into the {:noreply, socket} at the end of your event handler (or {:ok, socket} if it’s being called from mount).

The event doesn’t actually get pushed when you call push_event/3 - you are only queuing up the event to the socket, which will fire off when the updated socket is returned from the LiveView callback (e.g. handle_event/3)

1 Like

I haven’t used many push_events but the below is something that works for me currently. Might be worth trying to add phx: is a prefix in your JS for the handleEvent.

    window.addEventListener("phx:reset_editor", (e) => {
      editor.innerHTML = ""; 
      syncEditorToInput();
    });

Above and Below are in seperate hooks, just took them as examples.

  window.addEventListener("phx:scroll_bottom", (e) => {
    const messagesContainer = document.querySelector('.js-message-list');
    messagesContainer.scrollTop = messageContainers.scrollHeight;
  });
             
{:noreply, 
  socket
  |> assign(:message, @message)
  |> form_assign_to_form(ecto_change(Message, @message))
  |> push_event("reset_editor", %{})
  |> push_event("scroll_bottom", %{})
  |> push_patch(to: socket.assigns.path)
}