Phoenix LiveView v0.18 introduced the special attributes :let, :for and :if. In addition to the :if special attribute, I’d like to see an :else-like attribute.
The :if attribute is very useful for conditionally rendering blocks, but hiding a block is often accompanied by showing another block.
See the following example, which displays a message based on a user’s role:
As you can see, the second :if is defined as the opposite of the first :if. This allows us to display a fallback block in case the user is not an admin. But showing a fallback block is a common use case, so let us add a special :else attribute that can be used to show such blocks:
<p :if={@role == :admin}>Hello Admin</p>
<p :else>Hello other roles!</p>
In the above example, the second block is being displayed when the :if in the first block evaluates to false.
This is not an entirely new idea. For example, Vue has a v-else directive and Svelte also has a {:else}.
We also had a working solution before the :if and :for special attributes were added. As far as I know, the only reason those attributes were added was for syntax sugar, as the docs state:
:if and :for
It is a syntax sugar for <%= if .. do %> and <%= for .. do %> that can be used in regular HTML, function components, and slots.
Therefore, an :else attribute would align with the :if and :for attributes, even if its only purpose is to add some syntax sugar.
Your example doesn’t look much worse, I think. Still, given both options, I’d choose the inline option, which is actually a bit cleaner.
I’ve wanted this before but my general thoughts are:
If it’s a simple check with short blocks I don’t mind the negation, as in your example, or simply using the <%= %> syntax.
If there are larger blocks I prefer to extract to function components and do the conditional via a match as I don’t enjoy reading long if/else in templates, ie:
The number of times I need an else is quite low compared to lone ifs (this is, of course, just me)
This last one is pure speculation as I’ve never studied HEEx’s source, but else would have to be aware of its immediate previous sibling and I don’t believe there is precedent for this (closest would be slots checking they are not in other slots). I can imagine this being deemed not worth taking on unless there was overwhelming demand for it.
Having said all that if it were available I would use it, I just don’t personally want it that badly so have never bothered to bring it up myself.
I generally prefer this form. Part of the whole appeal of structured programming is that program structure dictates flow, so you do not have to scan through lines of code before knowing if they will be executed.
Conversely, the above is structure-less, and requires you check after reading any :if element if the next element is an :else to fully understand the output.
A year later, I find the older EEx form good for the clarity indentation brings, or extracting to components with pattern matching like the previous comments suggested sufficient for my needs.