Accessing LiveView assign that may not exist

Trying out my first Phoenix.Component with LiveView 0.16.1. I’ve run into an issue that’s not insurmountable but I’m wondering if there’s a better way that I’m missing.

Is there a way to access an assign that might or might not exist? In a regular map, obviously you could do Map.get(map, key), and it would return nil if the map has no such key. This does not work in an HEEX template: Map.get(@socket.assigns, :foo) is always nil because @socket.assigns is always %Phoenix.LiveView.Socket.AssignsNotInSocket{} during render.

I want to send the value of @foo as a Phoenix.Component attribute, but if it hasn’t been explicitly assigned, it raises. I can overcome this by assigning @foo to nil in each view where it is not otherwise assigned, but it seems like either I’m missing something or there’s a need for a function such as Phoenix.LiveView.maybe_get_assign(key, default_value \ nil) to access assigns that may or may not be set.

1 Like

Default them on mount to nil so they are always available

3 Likes

You can use the square-bracket notation to look up assigns that may not exist, e.g: assigns[:active]. This won’t crash the view if the active assign is missing, so I use it often in my templates, like lib/my_app_web/components/layouts/app.html.heex, which are used from lots of views.

@petrus-jvrensburg that is not recommended, as LiveView won’t be able to do proper change tracking and optimised diffs: Assigns and HEEx templates — Phoenix LiveView v0.20.1

I just put something like this in app.ex for assigns used in nav, etc:

  def render(assigns) do
    assigns =
      assigns
      |> assign_new(:page_title, fn -> nil end)
      |> assign_new(:page, fn -> nil end)
      |> assign_new(:selected_tab, fn -> nil end)
[...]