Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass plug loaded data to LiveView components

Hi I'm using different domain names to load different data sets. I'm currently using a custom plug to load the correct domain id based on the hostname. E.g. got this in my endpoint.ex just before the router:

plug WebApp.DomainCheck
socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]]
...
plug WebApp.Router

And

defmodule WebApp.DomainCheck do
  import Plug.Conn
  @behaviour Plug

  def init([]), do: []

  def call(conn, _options \\ []) do
    domains = Model.load_allowed_domains()
    case Map.get(domains, conn.host) do
      nil ->
        conn
        |> resp(401, "Domain not allowed")
        |> halt()

      domain_id ->
        conn
        |> assign(:domain_id, domain_id)
    end
  end
end

Now this works for normal View as I have the domain_id assign in each of them. But how do I get the domain data injected into my LiveViews as well from a plug?

Currently I've code duplicated the same domain check into every LiveViews mount() page:

defmodule WebApp.WelcomeLive do
  use WebApp, :live_view

  @impl true
  def mount(_args, _session, socket) do
    domains = Model.load_allowed_domains()
    host = socket.host_uri.host
    case Map.get(domains, host) do
      nil -> {:error, "Domain not allowed"}
      domain_id -> {:ok, assign(socket, :domain_id, domain_id)}
    end
  end

Is there any way I can make a plug effective in pushing this data down to the live views without need to add code to each mount?

like image 209
Dominic Avatar asked Nov 16 '25 17:11

Dominic


1 Answers

I had a similar use case in my app where my plug puts the a user struct on the assigns and I wanted to keep that data inside live view without reloading all stuff.

The only way I could achieve that was using the option session from the live route passing it a MFA.

In the router you will have something like

live "/page", WebApp.SomeLiveView, :show, session: {WebAppp.Helpers, :keep_domain_id, []}

and your WebApp.Helpers will have that function returning what you want to be passed to your live view as session.

defmodule WebApp.Helpers do
  def keep_domain_id(conn) do
    %{"domain_id" => conn.assigns.domain_id}
  end
end

Then in your mount on you will have "domain_id" key in your session

defmodule WebApp.WelcomeLive do
  use WebApp, :live_view

  @impl true
  def mount(_args, %{"domain_id" => domain} = _session, socket) do
    ...
  end
end
like image 178
Evaldo Bratti Avatar answered Nov 18 '25 20:11

Evaldo Bratti