mitkins
Pass in session data to a live view when instigated via a live route?
Is there any way to pass up session data via a live route to a live view controller? Specifically, I’d like to pass up the current authenticated user.
In my mount call I tried to make the following call:
current_user = Zoinks.Guardian.Plug.current_resource( socket.endpoint )
However, this fails with the following error:
[error] #PID<0.20188.5> running ZoinksWeb.Endpoint (connection #PID<0.20187.5>, stream id 1) terminated
Server: localhost:4000 (http)
Request: GET /tasks
** (exit) an exception was raised:
** (UndefinedFunctionError) function ZoinksWeb.Endpoint.private/0 is undefined or private
(zoinks) ZoinksWeb.Endpoint.private()
(guardian) lib/guardian/plug/pipeline.ex:203: Guardian.Plug.Pipeline.current_key/1
(guardian) lib/guardian/plug.ex:297: Guardian.Plug.fetch_key/2
(guardian) lib/guardian/plug.ex:127: Guardian.Plug.current_resource/2
(zoinks) lib/zoinks_web/live/task_live/index.ex:26: ZoinksWeb.TaskLive.Index.fetch/1
(zoinks) lib/zoinks_web/live/task_live/index.ex:15: ZoinksWeb.TaskLive.Index.mount/2
(phoenix_live_view) lib/phoenix_live_view/view.ex:332: Phoenix.LiveView.View.do_static_mount/3
(phoenix_live_view) lib/phoenix_live_view/view.ex:197: Phoenix.LiveView.View.static_render/3
(phoenix_live_view) lib/phoenix_live_view/controller.ex:39: Phoenix.LiveView.Controller.live_render/3
(phoenix) lib/phoenix/router.ex:275: Phoenix.Router.__call__/1
(zoinks) lib/plug/error_handler.ex:64: ZoinksWeb.Router.call/2
(zoinks) lib/zoinks_web/endpoint.ex:1: ZoinksWeb.Endpoint.plug_builder_call/2
(zoinks) lib/plug/debugger.ex:122: ZoinksWeb.Endpoint."call (overridable 3)"/2
(zoinks) lib/zoinks_web/endpoint.ex:1: ZoinksWeb.Endpoint.call/2
(phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:33: Phoenix.Endpoint.Cowboy2Handler.init/2
(cowboy) /Users/hamishmurphy/Documents/Elixir/zoinks/deps/cowboy/src/cowboy_handler.erl:41: :cowboy_handler.execute/2
(cowboy) /Users/hamishmurphy/Documents/Elixir/zoinks/deps/cowboy/src/cowboy_stream_h.erl:296: :cowboy_stream_h.execute/3
(cowboy) /Users/hamishmurphy/Documents/Elixir/zoinks/deps/cowboy/src/cowboy_stream_h.erl:274: :cowboy_stream_h.request_process/3
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
That’s because there is no ZoinksWeb.Endpoint.private[:guardian_key]. So it would be helpful if I could just pass up the data from the assigns that is already attached to the View. Is there some way I can do this?
Most Liked
chrismccord
You still need to provide the minimal session data necessary to fetch the current user. For example, if the LV disconnects or crashes and rejoins, you won’t have the current_user from the parent assigns, so you still need to pass the current_user.id to the LV session and your mount needs to fallback to fetching the user from the DB in the event of connection/error recovery: ie:
def mount(%{user_id: user_id} = _session, socket) do
{:ok, assign_new(socket, :current_user, fn -> Accounts.get_user!(user_id) end)}
end
mitkins
I’m not sure if this is helpful, but what I didn’t realise when I wrote the question is that I can do the following in my router.ex:
live "/tasks", TaskLive.Index, session: [ :guardian_default_token ]
:session is a list of keys that may exist in the Plug session (when the page is initially rendered). If they do exist, then the key/value pair is copied to the LiveView session (as a parameter in the mount function call). There’s more information in the documentation
In my case, I’m using Guardian. So once the user authenticates, I’m able to pass in the guardian_default_token session variable - which is stored as a secure cookie.
But to get the token stored as a session variable in the first place, I think it needs to be a part of a post back to the server? So I’m not sure that you can do this without a redirect? Please take the thought with a grain of salt - it’s only a guess
mitkins
Is there any way I can add the user_id key to the session without making an explicit call to live_render? This is what I have right now:
defmodule ZoinksWeb.Router do
pipeline :browser_auth do
plug Zoinks.Guardian.AuthPipeline
plug Zoinks.Guardian.CurrentUser
end
scope "/", ZoinksWeb do
pipe_through [:browser, :browser_auth]
live "/tasks", TaskLive.Index
end
end
Or do I need to switch out the live route with:
get "/tasks", TaskController, :index
And make the call to live_render like this?
defmodule ZoinksWeb.TaskController do
def index(conn, _params) do
live_render(conn, TasksLive.Index, session: %{
user_id: conn.assigns.current_user.id
})
end
end
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









