There comes a time in most applications where you will want to loop through an array of data on the front-end. In Aurelia we have the repeat.for
attribute which allows us to use Aurelia’s repeater functionality in our view templates.
Lets run through some examples and common scenarios when working with the repeater functionality.
Accessing the first item in the loop
Sometimes you want to style the first element differently or do something with the data, using the $first
conditional variable, we can determine whether or not the current item is the first in our loop of items. This value will either be true or false, making it a great candidate for the if
functionality for conditionally showing items.
<div repeat.for="item of items">
<div if.bind="$first">First item</div>
</div>
Accessing the last item in the loop
Just like our above example, we can determine if we have reached the end of our items array and we are displaying the last value using the $last
conditional value.
<div repeat.for="item of items">
<div if.bind="$last">Last item</div>
</div>
Conditional classes
A very common thing is wanting to conditionally change a class on an element, depending on a particular criteria. Using a ternary conditional in our view template, we can conditionally set classes on elements.
In the below example, you can replace $first
with whatever you want. As long as we return a boolean, we can conditionally put classes on elements inside of a loop.
<div repeat.for="item of items">
<div class="${ $first ? 'item-first-class' : '' }">Not first or last item</div>
</div>
Accessing middle items
Strangely enough the documentation doesn’t mention this conditional variable, but using the $middle
conditional variable, we can determine if an item is not the first or last item. Sometimes you want to style elements differently that aren’t the first or last, say for example removing borders or margin.
<div repeat.for="item of items">
<div if.bind="$middle">Not first or last item</div>
</div>
Accessing the current index value
When looping through an array, a counter is increment behind the scenes which determines the current place in the array an item is. Starting at 0, the $index
variable tells us at what place we are in the array loop.
This might be handy for displaying the current index in an ordered list type situation or perhaps displaying a list of tracks off of an album. If the below items array has 4 items, we’ll have an index range from 0 to 3.
<div repeat.for="item of items">
<div>${$index}</div>
</div>
Working with odd and even
Sometimes you might want to alternately style an item row, this is where $odd
and $even
come in handy. These conditional variables return boolean values which allow us to style or display rows depending on whether or not we’re currently on an odd or even item.
<div repeat.for="item of items">
<div if.bind="$odd">Odd item</div>
<div if.bind="$even">Even item</div>
</div>
Iterating Numbers
Sometimes you don’t want to iterate actual values, but rather just loop over a series of numbers instead. You might want this to generate a numbered list or numbers for some other reason. The syntax is not too different from that of looping real values.
<div repeat.for="i of 10">${i}</div>
That is seriously it. Crazy how simple Aurelia makes looping basically anything. Replace the number ten with whatever number you want to loop up until. Please note that values will start from 0, not 1. So you will get numbers from 0 to 9 instead of 1 to 10.
Limit The Number of Iterations
If you have experience working with Angular, you would be familiar with the ability to limit the number of values looped at once in a repeater. Doing this can increase the performance of your application quite substantially.
Unfortunately Aurelia does not ship with a way to do this, but using a simple value converter we can easily add in this functionality to our repeater loops.
Create the value convertor and save it as “limit-to.js” or whatever file extension you use:
export class LimitToValueConverter {
toView(array, count) {
return array.slice(0, count);
}
}
Now within your view templates, you can import and use the value convertor like so:
<require from="./limit-to"></require>
<div repeat.for="item of items | limitTo:5">${i}</div>
You’ll notice we are using our value convertor which we called “limitTo” and we specify a numeric value. This will allow you to limit the number of items looped in a repeater. Using bind, we can make this dynamic so in the instance of pagination or infinite scrolling situations.
Iterating A Map
A simple example of a map of key/value pairs being iterated. As you can see, we are mapping the keys in the first argument inside of square brackets.
<template>
<ul>
<li repeat.for="[id, customer] of customers">${id} ${customer.fullName}</li>
</ul>
</template>
Accessing the parent scope
Changes to the repeater functionality mean that needing to use a $parent variable to access the parent scope are no longer needed. The parent scope is automatically merged into the current scoped.
Thanks for the post. I was just looking for an elegant way to add a css class to the first item of <div repeat.for=""
Awesome write up! Thanks, Dwayne.
For anyone who doesn’t like having to use the $parent variable in the repeat.for loop, it is no longer needed. You can access the parent scope with or without it.
Thanks man, didn’t know that I can get only middle values. This helps me a lot.
Well done. This was a clean and useful reference.