sb logoToday I Learned

Avoid variables in your LiveView leex templates

In my phoenix templates, I have a tendency to use variables, especially for functions where I want to return multiple values. For example

# Template
<section>
  <% {color_class, indicator} = status_indicator(@match) %>
  <p class="<%= color_class %>">
    <%= indicator %>
  </p>
</section>

# View 
def status_icon(match) do
  case Match.status(match) do
    :prematch -> {"text-yellow-500", "prematch"}
    :live -> {"text-green-500", "live"}
  end
end

This is fine for a normal template, but with Phoenix LiveView, you’re running into a LiveEEX pitfall.

Avoid defining local variables, except within for, case, and friends

Using this method makes Phoenix LiveView opt out of change tracking, which means sending data over the wire everytime.

Instead, use multiple functions or call into another template:

# Multiple functions
<section>
  <p class="<%= status_indicator_color(@match) %>">
    <%= status_indicator(@match) %>
  </p>
</section>

# If your operation is expensive, do it once and call into another template 
<section>
  <%= render MatchView, "status_indicator.html", status: Match.status(@match) %>
</section>

# other template
<p class="<%= status_color(@status) %>">
  <%= status_indicator(@status) %>
</p>

# View
def status_color(status) do
  case status do
    :prematch -> "text-yellow-500"
    :live -> "text-green-500"
end

def status_indicator(status) do
  to_string(status)
end