DEV Community

Mykolas Mankevicius
Mykolas Mankevicius

Posted on • Edited on

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.

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!