One thing that irks me when working with LiveView is that if you define a live route in your router (e.g. live "/my-thing/:id", MyThing.Manage, :manage
), there’s no way to do anything with conn
for the initial page request other than creating separate scopes to attach plugs, which leads to ugly code like this:
scope "/workspaces", Thing do
pipe_through [:route1_specific_thing]
live "/route1", Thing.Route1, :route1
end
scope "/workspaces", Thing do
pipe_through [:route2_specific_thing]
live "/route2", Thing.Route2, :route2
end
scope "/workspaces", Thing do
pipe_through [:route3_specific_thing]
live "/route3", Thing.Route3, :route3
end
Another option is to use a regular route rather than a live route, but that then requires setting up a controller that does whatever you need to do with conn
, then calls live_render()
.
What I wish was possible would be another lifecycle hook for the live view (tentatively named route
), that would run before mount, with conn
in context, something like this:
defmodule Thing.Live.Manage do
use Phoenix.LiveView
def route(conn, params) do
# Mess with conn.assigns or do whatever.
conn
end
def mount(params, _session, socket) do
thing = load_thing(params)
{:ok,
assign(socket,
page_title: thing.name,
thing: thing.name,
workspace_id: params.workspace_id
)}
end
def render(assigns) do
~L"""
<h1> I LOVE HTML</h1>
"""
end
end
That would remove the need for extra controllers, and allow keeping all the live view’s code its own module.