Forem

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.

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

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!

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

👋 Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay