DEV Community

Mykolas Mankevicius
Mykolas Mankevicius

Posted on • Edited on

3 1

Phoenix LiveView is slot empty?

Here's a simple function to check if the slot is empty, where empty can mean.

  1. No slot provided
  2. Slot provided but has only whitespace
defp slot_empty?(slot) do
  case slot do
    [] ->
      true

    slots when is_list(slots) ->
      not Enum.any?(slots, fn slot ->
        case slot do
          %{inner_block: inner_block} when is_function(inner_block) ->
            try do
              {:ok,
                inner_block.(%{}, nil)
                |> Phoenix.HTML.html_escape()}
            rescue
              _ -> :error
            end
            |> case do
              {:ok, html} ->
                html
                |> Phoenix.HTML.safe_to_string()
                |> String.trim()
                |> Kernel.!=("")

              _ ->
                true
            end

          _ ->
            false
        end
      end)

    _ ->
      true
  end
end
Enter fullscreen mode Exit fullscreen mode

Example usage:

slot :inner_block

@spec heading(assigns :: map()) :: Rendered.t()
def heading(assigns) do
  ~H"""
  <header :if={not slot_empty?(@inner_block)} class="grid gap-4 pb-8 text-left">
    <%= render_slot(@inner_block) %>
  </header>
  """
end

Enter fullscreen mode Exit fullscreen mode

Hope this helps.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (2)

Collapse
 
datrader profile image
DaTrader

@neophen Make the code in the first case clause look as the code below so the function does not crash when a slot takes a :let argument that cannot be nil (because it expects a tuple or a map/structure):

    try do
      { :ok, 
        inner_block.( %{}, nil)
        |> Phoenix.HTML.html_escape()}
    rescue
      _ -> :error
    end
    |> case do
      { :ok, html} ->
        html
        |> Phoenix.HTML.safe_to_string()
        |> String.trim()
        |> Kernel.!=( "")

      _ ->
        true
    end
Enter fullscreen mode Exit fullscreen mode

An alternative would be to pass a structured argument to the function itself which would then supply it to the inner_block function, but that would just be an unnecessary burden for the caller.

Collapse
 
neophen profile image
Mykolas Mankevicius

Thank you, updated the code!

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more