Live_patch to same liveview - I think I found a liveview bug?

<nav>
  <%= live_patch to: Routes.page_path(@socket, :index) do %>
    Go Home
  <% end %>
</nav>

This is a shared navigation link in my header. If I click it from another liveview, it transitions correctly to the PageLive liveview.

Now if I click it again while I’m already in the PageLive liveview, I get a bug:

  • (UndefinedFunctionError) function ZZZWeb.PageLive.handle_params/3 is undefined or private
    (zzz 0.1.0) ZZZWeb.PageLive.handle_params(%{}, “http://localhost:4000/”, #Phoenix.LiveView.Socket<assigns: %{flash: %{}, live_action: :index}, changed: %{}, endpoint: ZZZWeb.Endpoint, id: “phx-Fpx0tpBMP5D1BR2R”, parent_pid: nil, root_pid: #PID<0.2665.0>, router: ZZZWeb.Router, transport_pid: #PID<0.2653.0>, view: ZZZWeb.PageLive, …>)

The fix is easy enough, I need to add a handle_params. But really it’s doing nothing, which is why I think this may be a bug. Maybe the default liveview macro needs a catch all like this for all liveviews?

def handle_params(_params, _uri, socket) do
  {:noreply, socket}
end

But wouldn’t it swallow legitimate missing function, when someone forgot to add a handle_params ? Maybe a handle_params(%{}, _uri, socket)default implementation or one with an warning asking for us to implement a catch all. Any thing could be helpful to explain why it happened

Yeah I meant specifically that, my bad:

handle_params(%{}, _uri, socket)

Otherwise you are correct it would swallow everything.

1 Like

Hi @sergio, live_patch is only meant for patching the current LiveView, not for navigating between LiveViews, so what you are experiencing is the intended behaviour. From the live_patch/2 docs:

When navigating to the current LiveView, Phoenix.LiveView.handle_params/3 is immediately invoked to handle the change of params and URL state. Then the new state is pushed to the client, without reloading the whole page while also maintaining the current scroll position. For live redirects to another LiveView, use live_redirect/2.

This is because LiveView is ignoring the patch (since the path is to another LiveView) and treating it as a regular link. handle_params/3 is an optional callback, unless you invoke live_patch, in which case it becomes a required callback. Hope that helps :slight_smile:

4 Likes

I see! The code produced by the live generators confused me a bit, I will use live_redirect to move around different live views. Thank you!

1 Like

Just be careful if you use iframes anywhere. Using a live_redirect will reload an iframe on page transition but live_patch won’t. That could be a deal breaker in certain types of apps where you want the iframe to not get disrupted (such as a video player) when moving between pages.

1 Like