Conditional Rendering

There are two ways to show and hide content in Aurelia. Conditional rendering allows you to use boolean logic to show and hide things inside Aurelia applications.

Aurelia supports two different ways of conditionally showing and hiding content.

if.bind

You can add or remove an element by specifying an if.bind on an element and passing in a true or false value.

When if.bind is passed false Aurelia will remove the element and all of its children from view. When an element is removed, if it is a custom element or has any associated events, it will be cleaned up, thus freeing up memory and other resources they were using.

In the following example, we pass a value called isLoading , which is populated whenever something is loading from the server. We will use it to show a loading message in our view.

<div if.bind="isLoading">Loading...</div>

When isLoading is a truthy value, the element will be displayed and added to the DOM. When isLoading is falsy, the element will be removed from the DOM, disposing of any events or child components.

else

There is also a else binding that allows you to create if/else statements too. The if/else functionality works how you might expect. Like Javascript, it allows you to say, "If this, otherwise that."

<div if.bind="showThis">Hello, there.</div>
<div else>Or else.</div>

The else value must be used on an element directly proceeding if.bind , or it will not work.

Using verbose syntax, you can opt out of caching if this becomes a problem.

<some-element if="value.bind: showThis; cache: false"></some-element>

When using the verbose syntax, value.bind is the boolean condition that triggers your if.bind condition and cache: false is what disables the cache. Only disable the cache if it becomes a problem.

show.bind

You can conditionally show or hide an element by specifying a show.bind and passing in a true or false value.

When show.bind is passed false , the element will be hidden, but unlike if.bind it will not be removed from the DOM. Any resources, events or bindings will remain. It's the equivalent of display: none; CSS, the element is hidden but not removed.

In the following example, we are passing a value called isLoading , which is populated whenever something is loading from the server. We will use it to show a loading message in our view.

When isLoading is a truthy value, the element will be visible. When isLoading is falsy, the element will be hidden but remain in view.

switch.bind

To deal with conditional rendering Aurelia also provides the switch template controller. It behaves like if/else in terms of that it does detach the elements from DOM, when the condition does not satisfy. The difference being is that it brings the intrinsic flexibility and semantics of using a switch statement with it.

A typical use-case of switch involves dealing with enums. For example, let's consider the following Status enum.

When tasked with displaying a specific text for a specific member (status) of the Status enum, with only if bind at our disposal, we may end up with the following markup.

Also if there are new statuses added to the Status enum in future, this markup will end up more verbose, and possibly difficult to understand. Moreover, the semantics of the code might as well be somewhat lost. With the usage of the switch/case template controller, the above markup can be written as following.

This behaves in similar fashion a switch in JavaScript behaves. That is it renders the first match, and ignores the rest. For example if the status has a value Status.processing, it will render <span>Processing your order.</span>. Note that it intrinsically avoids matching the following cases after the first match and consequently binding and rendering those elements. That is the basic and typical use-case of the switch/case template controllers. Now let's see some other features of this as well.

default-case

The switch also supports default-case; i.e. this "case" will be matched, if nothing else is matched.

With this markup, if the status is set to Status.unknown or Status.delivered, <span>Unknown.</span> will be rendered.

multi-case

It is possible to map a single element to multiple cases, by binding an array to the case.

For either of Status.received or Status.processing, it will render <span>Order received.</span>. A JavaScript equivalent of this would be the following.

When an array is bound to the case, the value of the switch is matched against the items in the array and not with the array reference.

fall-through

It is also possible to have the switch-case fallthrough in the markup, where you don't want to break after a case has been executed. This means something like this.

Aurelia equivalent of this will be the following.

Assuming that status is set to Status.received, it will end up the rendering the first two <span>s.

  • By default for every case fallThrough is set to false. If needed, you need to set it to true explicitly. This the reason why we don't need to write the following: <span case="value.bind:'processing'; fall-through.bind: false">Processing your order.</span>.

  • fall-through: true is a less verbose syntax for binding the value of fallThrough. In this case, the string 'true' and 'false' are converted to boolean true, and false respectively.

Miscellaneous examples

This section includes few more interesting examples that you might encounter in real life, and the statutory warnings.

  • Another usage of switch that we often see in the wild, is to use a static expression for switch and more dynamic expression for case. Therefore, the following is a valid usage of switch.

  • The switch can be used to provide conditional projection to au-slot. The following markup is rendered as '<foo-bar> <span>Order received.</span> </foo-bar>' with status set to Status.received.

  • The case can be used with <au-slot> element as well. The following markup is rendered as '<foo-bar> <div> <span>Projection</span> </div> </foo-bar>' with status set to Status.received.

  • switchs can be nested. For example, the following markup is rendered as <span> Expected to be delivered in 2 days. </span> with status set to Status.delivered.

  • switch can work without any case attribute in it. However, the case cannot be used with the switch applied to its parent. This applies to the default-case as well.

  • In fact, it is worth noting that case should be the direct child of switch. For most of the cases Aurelia will throw error otherwise; for other cases, it might lead to unexpected results. If you think, any of the following should be supported, then let us know your use-case.

Last updated

Was this helpful?