Phoenix live view adding action_name from controller

I am having the following menu renderer:

<%= render "navbar_item.html", conn: @conn, action: :index, text: "Home" %>

Where the navbar_item.html is defined as

<%= if action_name(@conn) == @action do %>
<li class="active">
  <% else %>
<li>
  <% end %>

  <%= link @text, to: Routes.page_path(@conn, @action) %>
</li>

This code work fine in all regular pages. But when it comes to Phoenix Live Views, I am getting

** (exit) an exception was raised:
    ** (KeyError) key :phoenix_action not found in: %{...}

Is there a way to populate PLV with the action_name?

4 Likes

I’m using this pattern matching to get the action name in phoenix live view:

{_live_view, [action: action_name, router: _router]} = conn.private[:phoenix_live_view]

But I thing there is a better way for this

1 Like

I ran into this same hurdle when adding Bodyguard to my navigation menu and needing to pass the controller :action for authz - and my navigation component is in the root template layout.

Now I am second guessing if I am going about this correct, as it seems there should be a Phoenix.LiveController.action_name

I ended up writing this horrendously coded helper function - but it works.

  def get_action_name(conn) do
    case Map.fetch(conn.private, :phoenix_live_view) do
      {:ok, phoenix_live_view} -> 
        {_live_view, [action: action_name, router: _router], _} = phoenix_live_view
        action_name
      :error -> Phoenix.Controller.action_name(conn)
    end
  end
1 Like