rhcarvalho

rhcarvalho

Is there an "else" to :if syntax in Heex templates?

Asking to get a sense of what other people are doing with their template logic…

The template code

I’m reading some third-party template code like this:

      <li :if={message.role == :function_call} class="...">
        ...
              <.icon_for_role role={message.role} />
       ...
      </li>
      <li :if={message.role != :function_call} class="...">
        ...
              <.icon_for_role role={message.role} />
        ...
            <.markdown :if={message.role == :assistant} text={message.content} />
            <span :if={message.role != :assistant} >
              ...
            </span>
        ...
      </li>

In more than one occasion there’s a tag with an :if attribute immediately followed by a sibling tag with another :if that is the negation of the previous condition.

I realized a casual search of the docs for :if (Search for terms beginning with colon (e.g. ":if") · Issue #1820 · elixir-lang/ex_doc · GitHub) doesn’t work, but nonetheless found Components and HEEx — Phoenix v1.8.8. Docs and local code searches suggest there’s only :if and :for, no :else.

I wonder what other people are doing for cases like that? Repeating+negating conditions feels error prone to me.

How I think it should be written

I think <%= if %> ... <% else %> ... <% end %> would be more appropriate for template code like above? Or even <%= case %> and <%= cond %> for the more general cases?

I know JS frameworks like Vue have <tag v-if="condition">...</tag><tag v-else>...</tag>, but would not propose making Heex have even more ways to accomplish things that are already possible with existing syntax :smile:

What do you normally do in cases like that?

First 10 of 11 Posts Switch mode

benregn

benregn

Edit: didn’t notice that you were talking about :if

Kurisu

Kurisu

I just got an idea. Why not create one’s own component named if or so.
It could be used like below.

<.if true={true}>
  This is true!
  <:else>
    That's false!
  </:else>
</.if>

So basically we have the if component which has a true attribute to check a condition and an else slot to render something when the condition passed to true won’t met. Otherwise the content in the inner_block will be the one to be rendered.

knoebber

knoebber

I don’t think an :else would make sense in heex syntax since it would be ambigous which clause it applied to.

But, what about :unless={} ?

Kurisu

Kurisu

Still, which previous :if would this :unless correspond to? I ask because I think what the OP is looking for is a way of not having to check a condition when a previous tag has already checked the negation of that same condition.

Then perhaps you’re saying that any :unless that follows a :if at the same nesting level should be considered the negation of that :if? In that case, the :unless wouldn’t even need to specify a condition.

Kurisu

Kurisu

An improved version could be as follows. The only drawback would be to have to define a component for every tag we want to apply this to.

<.li cond={true}>
  This is true!
  <:unless>
    That's false!
  </:unless>
</.li>
knoebber

knoebber

:unless={condition} would be a short hand for :if={!condition} , no previous clause needed. I’m only suggesting it because elixir already has it: Kernel — Elixir v1.16.3 (just not in heex).

Kurisu

Kurisu

Thanks for the clarification.

Personally I don’t think it will add anything, except perhaps aesthetics for those who like this form.

I suppose that :if or :unless thing is actually more for checking that a condition is met without worrying about what happens if it’s not.

If we want to do something more complex, I think we can simply use <%= if %> ... <% else %> ... <% end %> as suggested by the OP. ^^

rhcarvalho

rhcarvalho OP

Thanks for the replies!

Yeah, I’m just more certain I would not like to learn more syntax (and inflict the same learning on everyone else) and have so many ways to accomplish the same things :smile:

shepelevstas

shepelevstas

Isn’t <%= if(cond?) do %> ... <% else %> ... <% end %> a standard heex syntax predating :if={cond?} that still works?

rhcarvalho

rhcarvalho OP

Yes, it is. And to this day the :if attribute doesn’t have an else counterpart, which is okay. My OP was trying to understand why people would use :if={cond} immediately followed by :if={!cond}, instead of using the older {%= if cond do %}...{% else %}...{% end %}.

I guess it’s just a matter of personal preference, sensibilities, style. No deep revelation :slight_smile:

Where Next?

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
jonnycharles
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
spammy
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
silverdr
Using Phoenix.LiveView.TagEngine as an EEx.Engine is deprecated! To compile HEEx, use Phoenix.LiveView.TagEngine.compile/2 instead. Sta...
New
dli
Before I dive in myself, did anyone successfully sprinkle Hologram into their existing LiveView app? Looking for hints regarding: Addi...
New
bottlenecked
Hi all, I wanted to ask how the community is dealing with post-release steps. Today we have Ecto migrations, which make sure that the db...
New
michallepicki
I am using Oban and occasionally, shortly after a deployment, a handful of jobs can fail because of dependency on other parts of the syst...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
type1fool
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
akoutmos
@hugobarauna and I (Alex Koutmos) have been hard at work on writing a book on Nerves that takes you from simply blinking LEDs to building...
New

We're in Beta

About us Mission Statement