How to pass data from the assigns in the first mount call to the second mount in LiveView

Hello,

I am building a website that has several agencies, each of them, related to one domain.

I need to get the agency data in the assigns, similar to what we do with :current_user.

The user information is stored in the session, but I can’t do that. It won’t make sense store the agency information in the session.

What I have done:

  1. I have added plug :fetch_current_agency to the browser pipeline. For testing purposes the function does nothing yet, but return an arbitrary string:
  def fetch_current_agency(conn, _opts) do
    # Here I should return and %Agency{} but for simplicity and testing purposes
    # I return the host only
    assign(conn, :agency, conn.host)
  end
  1. On the on_mount callback, I call :ensure_agency. This is the function:
def on_mount(:ensure_agency, _params, session, socket) do
    # Note the agency fallback is only for testing purposes and to make the code simpler
    socket = Phoenix.Component.assign_new(socket, :agency, fn -> "Agency fallback" end)

    IO.puts("Socket agecny: #{socket.assigns.agency}")

    {:cont, socket}
end

On the on_mountcallback, I get the agency right in the first mount call, which is the host. But on the second time, I get the fallback value Agency fallback

My question is, how can I persist the agency data in the assigns?

In this simplified code, I’d like to have the host’s value on the assigns every time so I can access it later in the live views.

Thanks!

3 Likes

Thanks @LostKobrakai ! Your article is very good and helped me to find a way to implement what I need.

After reading it, I investigated how the session data is passed to the WebSocket, and I learned about Phoenix.LiveView.Socket and the connect_info parameters.

I found in the docs of get_connect_info/2 that it accepts the parameters: :peer_data, :trace_context_headers, :x_headers, :uri, and :user_agent.

And :uri is exactly what I need!

More valuable docs in the Phoenix Endpoint

I inspected the WebSocket and saw the session data but not the URI data. Is it encoded inside the session?

Thanks!

You explicitly need to tell the socket which information you need in the connect info. E.g. directly from the macro documentation for socket/3:

socket "/socket", AppWeb.UserSocket,
      websocket: [
        connect_info: [:peer_data, :trace_context_headers, :x_headers, :uri, session: [store: :cookie]]
      ]