jejuro

jejuro

LiveviewAppWeb.Router.Helpers.live_path/3 is undefined

I am combining the code in the book, Building Table Views with Phoenix LiveView on to that of the book, Programming Phoenix LiveView", to deepen my understanding of the books. The former uses some older version of LiveView, and the latter uses the latest.

I hope some advices from those who read the two. I don’t completely understand how routes are composed and work by the Router.

From user inputs in a live_component, SortingComponent, I need to assemble a new path using Route.live_path in the live_view module, Index, which is the parent of the live_component. Below is the error.

  1. ** (UndefinedFunctionError) function Routes.live_path/3 is undefined (module Routes is not available) - this error is shown when I extract a new path from user inputs onto a live component. There was a similar question about 2 years ago, link.
    Below is where error arose in the Index live_view module. I changed puch_patch to push_navigate.
def handle_info({:update, params}, socket) do
    # call handle_params
    handle_params(params, "dummy", socket)

    path = Routes.live_path(socket, __MODULE__, params)
    {:noreply, push_navigate(socket, to: path, replace: true)}
end

I also changed helpers: false to true, use Phoenix.Router, helpers: true and added alias of alias MarketWeb.Router.Helpers, as: Routes to the Index module, but not works.

** (ArgumentError) no action MarketWeb.ProductLive.Index for MarketWeb.Router.Helpers.live_path/3. The following actions/clauses are supported:

    live_path(conn_or_endpoint, MarketWeb.ProductLive, params \\ [])
    live_path(conn_or_endpoint, MarketWeb.WrongLive, params \\ [])
    (phoenix 1.7.2) lib/phoenix/router/helpers.ex:328: Phoenix.Router.Helpers.invalid_route_error/3
    (market 0.1.0) lib/market_web/live/product_live/index.ex:85: MarketWeb.ProductLive.Index.handle_info/2
    (phoenix_live_view 0.18.18) lib/phoenix_live_view/channel.ex:276: Phoenix.LiveView.Channel.handle_info/2

iex> Routes.__info__(:functions) shows live_path/2 and live_path/3. So there definately are routes.

Below are my phx.routes

❯ mix phx.routes
                          page_path  GET     /                                      MarketWeb.PageController :home
                live_dashboard_path  GET     /dev/dashboard                         Phoenix.LiveDashboard.PageLive :home
                live_dashboard_path  GET     /dev/dashboard/:page                   Phoenix.LiveDashboard.PageLive :page
                live_dashboard_path  GET     /dev/dashboard/:node/:page             Phoenix.LiveDashboard.PageLive :page
                                     *       /dev/mailbox                           Plug.Swoosh.MailboxPreview []
             user_registration_path  GET     /users/register                        MarketWeb.UserRegistrationLive :new
                    user_login_path  GET     /users/log_in                          MarketWeb.UserLoginLive :new
          user_forgot_password_path  GET     /users/reset_password                  MarketWeb.UserForgotPasswordLive :new
           user_reset_password_path  GET     /users/reset_password/:token           MarketWeb.UserResetPasswordLive :edit
                  user_session_path  POST    /users/log_in                          MarketWeb.UserSessionController :create
                 user_settings_path  GET     /users/settings                        MarketWeb.UserSettingsLive :edit
                 user_settings_path  GET     /users/settings/confirm_email/:token   MarketWeb.UserSettingsLive :confirm_email
                          live_path  GET     /guess                                 MarketWeb.WrongLive MarketWeb.WrongLive
                          live_path  GET     /                                      MarketWeb.ProductLive MarketWeb.ProductLive
                 product_index_path  GET     /products                              MarketWeb.ProductLive.Index :index
                 product_index_path  GET     /products/new                          MarketWeb.ProductLive.Index :new
                 product_index_path  GET     /products/:id/edit                     MarketWeb.ProductLive.Index :edit
                  product_show_path  GET     /products/:id                          MarketWeb.ProductLive.Show :show
                  product_show_path  GET     /products/:id/show/edit                MarketWeb.ProductLive.Show :edit
                  user_session_path  DELETE  /users/log_out                         MarketWeb.UserSessionController :delete
             user_confirmation_path  GET     /users/confirm/:token                  MarketWeb.UserConfirmationLive :edit
user_confirmation_instructions_path  GET     /users/confirm                         MarketWeb.UserConfirmationInstructionsLive :new
                          websocket  WS      /live/websocket                        Phoenix.LiveView.Socket
                           longpoll  GET     /live/longpoll                         Phoenix.LiveView.Socket
                           longpoll  POST    /live/longpoll                         Phoenix.LiveView.Socket
  1. Because Route.live_patch doesn’t work, I just tried to manually change the path by hand to see what happens, {:noreply, push_navigate(socket, to: "/?page=1&page_size=20&sort_by=id&sort_dir=desc", replace: true)} in the handle_info(:update, ...) function of the Index live_view module. Even in this case, the expected product sorting doesn’t works. Though there is no more errors, the web page of the new address shows nothing but the welcome index page.

Thank you for reading this long & tedious question.

Most Liked

jejuro

jejuro

Below are the index module I have a little bit modified the code from the book, Programming Phoenix LiveView, Beta 0.9, Part 1, to combine the SortingComponent of the book, Building Table Views with Phoenix LiveView .

defmodule MarketWeb.ProductLive.Index do
  use MarketWeb, :live_view

  alias MarketWeb.Router.Helpers, as: Routes

  alias Market.Catalog
  alias Market.Catalog.Product
  alias MarketWeb.Forms.SortingForm

  require Logger

  @impl true
  def mount(_params, _session, socket) do
    {:ok, stream(socket, :products, Catalog.list_products())}
    # {:ok, stream(socket, :products, [nil])}
  end

  @impl true
  def handle_params(params, _url, socket) do
    IO.inspect(params, label: "handle_params, params")
    socket =
      socket
      |> parse_params(params)
      # |> IO.inspect
      |> assign_products()

    {:noreply, apply_action(socket, socket.assigns.live_action, params)}
  end

  defp parse_params(socket, params) do
    with {:ok, sorting_opts} <- SortingForm.parse(params) do
      assign_sorting(socket, sorting_opts)
    else
      _error ->
        assign_sorting(socket)
    end
  end

  defp assign_sorting(socket, overrides \\ %{}) do
    opts = Map.merge(SortingForm.default_values(), overrides)
    assign(socket, :sorting, opts) # |> IO.inspect
  end

  # Update assign_products/1 like this:
  defp assign_products(socket) do
    %{sorting: sorting} = socket.assigns

    assign(socket, :products, Catalog.list_products(sorting))
  end

  defp apply_action(socket, :edit, %{"id" => id}) do
    socket
    |> assign(:page_title, "Edit Product")
    |> assign(:product, Catalog.get_product!(id))
  end

  defp apply_action(socket, :new, _params) do
    socket
    |> assign(:page_title, "New Product")
    |> assign(:product, %Product{})
  end

  defp apply_action(socket, :index, params) do
    IO.inspect(params, label: "apply_action, :index, params")
    socket
    |> assign(:page_title, "Listing Products")
    |> assign(:product, Catalog.list_products(params))
  end

  def handle_info({:update, params}, socket) do
    # IO.puts "ProductLive.handle_info({:update, params}, socket)"
    # IO.inspect(params, label: "params")

    # params = merge_and_sanitize_params(socket, params) # (1) delete nil values, (2) preserve old values in socket.assigns

    # IO.inspect(params, label: "params")

    # call handle_params
    Logger.info "handling query"
    IO.inspect(params, label: "params")
    handle_params(params, "dummy", socket)

    # path = Routes.live_path(socket, __MODULE__, params)
    # {:noreply, push_navigate(socket, to: path, replace: true)}
    {:noreply, push_navigate(socket, to: "/?page=1&page_size=20&sort_by=id&sort_dir=desc", replace: true)}
    # {:noreply, push_navigate(socket, to: "/products", replace: true)}
  end

  @impl true
  def handle_info({MarketWeb.ProductLive.FormComponent, {:saved, product}}, socket) do
    {:noreply, stream_insert(socket, :products, product)}
  end

  @impl true
  def handle_event("delete", %{"id" => id}, socket) do
    product = Catalog.get_product!(id)
    {:ok, _} = Catalog.delete_product(product)

    {:noreply, stream_delete(socket, :products, product)}
  end
end

Where Next?

Popular in Questions Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
yawaramin
In the Dialyzer docs ( dialyzer — OTP 29.0.2 (dialyzer 6.0.1) ), there is a way to turn off a specific warning for a function: -dialyzer...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Other popular topics Top

New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New

We're in Beta

About us Mission Statement