mitkins

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

chrismccord

Creator of Phoenix

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

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

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

Where Next?

Popular in Questions Top

chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
nobody
How to bind a phoenix app to a specific ip address? could not find anything about that, nowhere, unfortunately, but for me this is quite...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
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
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Other popular topics Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
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
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New

We're in Beta

About us Mission Statement