Default assigns in LiveView

I’m trying to make a little library similar to how Phoenix.Flash works, but I can’t figure out how to make a default assign that gets carried over to LiveView.

I made a plug…

defmodule Web.LiveNotifyPlug do
  import Plug.Conn

  def init(opts \\ []), do: opts

  def call(conn, _opts) do
    assign(conn, :live_notify, nil)
  end
end

But that assign is not available in any LV render function.

Thanks for the help.

You must use assign_new/3 in a LiveView mount/3 callback to assign a value from the Plug pipeline:

defmodule Web.ExampleLive do
  use Phoenix.LiveView

  @impl Phoenix.LiveView
  def mount(_params, _session, socket) do
    {:ok, assign_new(socket, :live_notify, fn -> nil end)}
  end
end

If the key already exists in the Plug.Conn assigns, it will be copied to the LiveView.Socket assigns. If it does not exist, then the function in the 3rd argument will be invoked to retrieve the value.

Note that this means the value from the Plug pipeline is only available during the initial static mount/render. Your library will need to provide another way for the LiveView to retrieve the value on a live mount/render, for instance with an on_mount/1 lifecycle hook:

defmodule Web.ExampleLive do
  @moduledoc "Userland LiveView module"
  use Phoenix.LiveView

  on_mount LiveNotify
  # or on_mount {LiveNotify, arg} if the user needs to supply data

  # callbacks...
end

Your library defines an on_mount/4 function that will be invoked immediately before the LiveView mount callback:

defmodule LiveNotify do
  @moduledoc "Library module"

  # :default is the default argument if none was provided
  def on_mount(:default, _params, _session, socket) do
    {:cont, apply_live_notify(socket)}
  end
  
  def on_mount(_arg, _params, _session, socket) do
    {:cont, apply_live_notify(socket)}
  end

  defp apply_live_notify(socket) do
    assign_new(socket, :live_notify, fn -> nil end)
  end
end

Let me know if that makes sense! :slight_smile:

3 Likes

Nice! on_mount is what I was looking for. So my use LiveNotify can just define the on_mount. Thank you.

But in the mean time, I found out that assigns[:live_notify] won’t raise an error, so that worked too… :slight_smile: