LiveviewAppWeb.Router.Helpers.live_path/3 is undefined or private

Hi, when clicking a pagination link, I’m seeing the following within the logs:

** (UndefinedFunctionError) function LiveviewAppWeb.Router.Helpers.live_path/3 is undefined or private

I have created the Phoenix application as follows:

mix phx.new liveview_app --live

Next, I have added and configured version 2.7 of scrivener_ecto package to perform pagination. the source for the application can be found here.

Is there something that I’m missing in regards to the index.ex and/or the index.html.leex files?

the helper live_path has a arity of 2.

There are two separate issues in your code in that same line, which you can fix quite easily and help improve your LiveView mental model.

Route helpers

The ‘live_path’ function will only be generated when you set a live path with a nil action in your router, as per the live/4 docs example:

 scope "/", LiveviewAppWeb do
    pipe_through :browser

    live "/thermostat", ThermostatLive
end

allows you to reference that route as live_path(@socket, ThermostatLive).

If you have a look at the named helpers defined for you from the live routes you set in router.ex, you’ll see there is no live_path.

iex> alias LiveViewAppWeb.Router.Helpers, as: Routes
iex> Routes.__info__(:functions)
[
  live_dashboard_path: 2,
  live_dashboard_path: 3,
  live_dashboard_path: 4,
  live_dashboard_path: 5,
  live_dashboard_url: 2,
  live_dashboard_url: 3,
  live_dashboard_url: 4,
  live_dashboard_url: 5,
  path: 2,
  static_integrity: 2,
  static_path: 2,
  static_url: 2,
  url: 1,
  user_index_path: 2,
  user_index_path: 3,
  user_index_path: 4,
  user_index_url: 2,
  user_index_url: 3,
  user_index_url: 4,
  user_show_path: 3,
  user_show_path: 4,
  user_show_url: 3,
  user_show_url: 4
]

Since your route is defined as live "/", UsersLive.Index, :index, your path
function should be Routes.user_index_path(socket, :index, page: page).

live_ vs push_, and _patch vs _redirect

The live_patch/2 and live_redirect/2 functions are for generating links in your markup templates, which your users will click to execute the corresponding LiveView changes.

The push_ variants are for you to use programatically in your controllers, which annotate the socket to perform the desired action.

Then, when you want to keep the user in the same LiveView but change something about it, like pagination in your case, you should rather use the _patch/2 functions. This will update the current socket state and “patch” the page’s path params for the user, as opposed to _redirect/2, which is used to change to a different LiveView and therefore closes the socket connection and starts up a new one.

Putting it all together, lib/liveview_app_web/live/user_live/index.ex:56 should be:
{:noreply, push_patch(socket, to: Routes.user_index_path(socket, :index, page: page))}

7 Likes

There is also a live_path/3 when live_path/2 is generated, for passing in params:

iex> h Routes.live_path

                    def live_path(conn_or_endpoint, action)                     


                def live_path(conn_or_endpoint, action, params)                 

iex> Routes.live_path(Endpoint, ThermostatLive, page: 2) 
"/thermostat?page=2"
2 Likes

@03juan Thanks for the write-up here and I appreciate it. BTW, the following didn’t work for me:

iex> alias LiveViewAppWeb.Router.Helpers, as: Routes
iex> Routes.__info__(:functions)

This might be caused by the version of Phoenix, Elixir, and/or Erlang but I’m able to get an idea of what route helpers exist using mix phx.routes. Again, thanks so much for the write-up and I definitely have some more LiveView to learn.

1 Like

You’re most welcome. Thank you for the reminder that others may not be using the same dep versions. Those functions worked for me on Erlang 24, Elixir 1.12.1, and Phoenix 1.5.9.

1 Like