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

3

8

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?

Outofdoor answered 11/11, 2014 at 10:9 Comment(2)
@Р̀СТȢѸ́ФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ, can you please change your username to something less obnoxious?Arvad
That's a good question.Transcontinental
A
8

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

Adamite answered 27/7, 2015 at 22:47 Comment(0)
A
6

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).

Arndt answered 13/4, 2015 at 15:40 Comment(2)
How do use this approach when using {{#each this}}?Presidentelect
I had trouble with this when list was an array of objects and elem was an object as well. It would never return true. So I just had to the edit the third line to something like this for it to work: return _.last(list)._id == elem._id;Miscreance
B
1

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.

Bestraddle answered 20/11, 2014 at 9:55 Comment(2)
Great @peppe, and if I was using a Meteor Collection instead of a simple array?Haskel
@GerardCarbó, the same principal applies to collections (retrieve the array via TheCollection.find().fetch()): if no documents are added, updated or removed, this solution works like a charm.Bestraddle

© 2022 - 2024 — McMap. All rights reserved.