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!