In Meteor using #each, check if 'last' element in the collection reached

3.3k Views Asked by At

I'm iterating through a collection in Meteor using {{#each}} and I would like to know if I'm in the last element, as I can do in AngularJS while using ngRepeat with $last.

It could be used, for example to construct human readable enumerations like 'I like cats, dogs and dolphins' :

Template.myTemplate.helpers({
    likedAnimals: function(){return ['dogs','cats','dolphins'];}
});

<template name='myTemplate'>
    I like  
    {{#each likedAnimals}}
        {{#if !$first && !$last}}, {{/if}}
        {{#if $last}} and {{/if}}
        {{this}}
    {{/each}}
</template>

Is there any way to check this condition in Meteor?

3

There are 3 best solutions below

2
On

This isn't supported in meteor yet (version 1.0), but you can kind of add it yourself by doing something like this:

Template.myTemplate.helpers({
    likedAnimals: function(){
        var animals = ['dogs','cats','dolphins']
        return animals.map(function(animal, index){
            return {
                name: animal,
                isFirst: index==0,
                isLast: index==animals.length-1
            }
        })
    }
})

However, this does not play nice with reactivity (making it work properly with reactivity is much harder, which I guess is the reason why this isn't a built in feature yet), but if you return a simple array that's not dependent on any reactive data source, this should work fine.

0
On

If any of you are wondering how to do the same with collection cursors, there's a much simpler way thanks to handlebar-helpers package.

You could then use:

$mapped - will map $first, $last, and $index onto your cursor or array

combined with $last helper in your template like that:

{{#each $mapped myCursor}}
  {{name}}{{#unless $last}},{{/unless}}
{{/each}}

PS: this also works with arrays

2
On

Using underscore.js :

Template.registerHelper('last',
    function(list, elem) {
        return _.last(list) === elem;
    }
);

<template name='myTemplate'>
    {{#each likedAnimals}}
        {{#if last ../likedAnimals this}} I'm the last ! {{/if}}
    {{/each}}
</template>

Worked with a reactive data source for me with meteor 1.1.0.1 (I don't know when Template.parentData() was introduced in meteor).