Can't use for-variable in heex - {if for_var == ...} - Protocol.UndefinedError

Why do I get Protocol.UndefinedError for this code?

~H"""
<%= for index <- [0, 1, 2] do %>
  <div {if 1 == index, do: [selected: ""]} ><%= index %></div>
<% end %>
"""
(Protocol.UndefinedError) protocol Enumerable not implemented for nil of type Atom
elixir          1.12.2-otp-23   /home/sf/.tool-versions
erlang          23.3.4.4        /home/sf/.tool-versions
Phoenix installer v1.6.0

btw, this works:

<div selected={1==index}><%= index %></div>

and produces a boolean attribute

<div>0</div>
<div selected>1</div>
<div>2</div>

nice.

I guess because the if statement will return nil by default if the check is false.

3 Likes

I haven’t used HEEx yet but shouldn’t this
<div {if 1 == index, do: [selected: ""]} ><%= index %></div>
be
<div {if 1 == index, do: [selected: ""], else: []} ><%= index %></div>

From here it says it should be keyword list or map Views and templates — Phoenix v1.6.0 because you don’t have else returning [] it’s neither.

2 Likes

:roll_eyes:

, else: []

fixes it. thanks guys.

3 Likes

It would be nice if it supported nil as well.

1 Like
<div {%{selected: index == 1}}><%= index %></div>
6 Likes

the shortest I found (by accident) is:

<div boolean_attr={@one == 1}>boolean_attr</div>

I’d like a list of heex-recepies.
Here are some (including stupid ones):

<div {@dynamic_attr}>dynamic_attr from assign</div>
<div {@dynamic_attr} static_attr="is-static">dynamic_attr with static attribute</div>
<div boolean_attr={@one == 1}>boolean_attr</div>
<div {%{boolean_attr: @one == 1}}>boolean_attr from dict</div>
<div {if @one == 1, do: [boolean_attr: ""], else: []}>boolean_attr kw-list from if</div>
<div {if @one == 1, do: %{boolean_attr: ""}, else: %{}}>boolean_attr dict from if</div>
<div some_attr={if @one == 1, do: "one-is-one"}>value from if</div>
<div some_attr={if @one == 0, do: "one-is-zero", else: "one-is-one"}>value from if/else</div>
<div class={"some_class #{if(@one == 1, do: " optional_class", else: "")}"}>interpolation</div>
<div class={"some_class" <> if @one == 1, do: " optional_class", else: ""}>concatenation 1</div>
<div class={"some_class" <> if @one == 0, do: " optional_class", else: ""}>concatenation 2</div>
<div {heex_helper(@some_state)}>dynamic_attr from helper function</div>
<div case={
      case @one do
        1 -> "one-is-one"
        _ -> "one-is-not-one"
      end
      }>
  case
</div>
3 Likes

Yup heex will exclude the attributes for falsey values