Only some LiveView's not working after update

I’ve been using an old version of LiveView and it’s been fine. However, I wanted to update to the latest LiveView.

However, about half of my LiveView’s don’t work after updating and I can’t figure out the solution. Part of the issue is that apparently identically structured LiveView pages work fine with the same controller and router.

Here’s the error:

    ** (ArgumentError) cannot invoke handle_params/3 on WebAppWeb.SpotHistoryLive because it is not mounted nor accessed through the router live/3 macro

It seems related to a known issue. Something to do with changes to how layouts work. However I just can’t figure out why some work fine and others don’t. Here’s my router:

  scope "/", WebAppWeb do
    pipe_through [:browser, :dashboard_layout]

    get "/", LivePageController, :index # works
    get "/calibration.html", LivePageController, :calibration_index # works
    get "/data-history.html", LivePageController, :history_index # works
    get "/other-data.html", LivePageController, :other_history_index # doesn't work
    get "/more-history.html", LivePageController, :more_history_index # doesn't work
    get "/settings.html", LivePageController, :settings_index # works
  end

Here’s a sample of the controller:


defmodule WebAppWeb.LivePageController do
  use WebAppWeb, :controller
  require Logger

  import Phoenix.LiveView.Controller

  def index(conn, _params) do
    conn
    |> assign(:page_title, WebAppWeb.DashBoardLive.title())
    |> live_render(WebAppWeb.DashBoardLive, session: %{"foo" => "bar2"})
  end

  def calibration_index(conn, _params) do
    conn
    |> assign(:page_title, WebAppWeb.CalibrationLive.title())
    |> live_render(WebAppWeb.CalibrationLive, session: %{})
  end

  def history_index(conn, _params) do
    conn
    |> assign(:page_title, WebAppWeb.DataHistoryLive.title())
    |> live_render(WebAppWeb.DataHistoryLive, session: %{})
  end

  def other_history_index(conn, _params) do
    conn
    |> assign(:page_title, WebAppWeb.OtherHistoryLive.title())
    |> live_render(WebAppWeb.OtherHistoryLive, session: %{})
  end

I’m not sure what’s different about the two other_history and more_history LiveViews. They import the same modules, provide the same mount and render functions.

The update was from LV 0.4 to LV 0.15 and Phoenix 1.5.

Any tips would be appreciated!

Do you make use of any live navigation: live_patch, live_redirect?

Yes, and only in those two LV pages. I tried commenting out all live_redirect's in one of the LV’s and it still results in the same error.

The other pages still work fine.

Ok, figured out it’s the handle_params/3 I was using as part of the live_redirect setup. When they’re present the LiveView only appears to work through the live router macro.

So it seems I need to use the live router macro to use those. However, when I try that then it doesn’t use my common “dashboard” layout that all the rest of my views use. It just returns only the LV render itself but none of the header or styling.

Do I need to look into the new liveview layout stuff then?

Ok resolved the issues. Yes it appears that you can use LiveView’s but not pass the parameters through the old get/post router macros. When you add a handle_params/3 it will break as the router isn’t configured for LV + params.

Converting the layouts to use the live router macros works but appears to not use the same layout plugs/names. Fixing this I just went with the root layout as it works across all my pages. I changed this:

plug :put_layout, {WebAppWeb.LayoutView, :app}

To this:

plug :put_root_layout, {WebAppWeb.LayoutView, :app}

This appears to fix my rendering issues. Perhaps at some point I’d refactor individual LV pages to use different app layouts, but that’s not needed here.

This also works FWIW:

  scope "/", WebAppWeb do
    live "/other-history.html", OtherHistoryLive, layout: {WebAppWeb.LayoutView, "app.html"}
end
3 Likes