How to Get the Index of an Array in a Meteor Template Each Loop

How can I get the index of an array in a Meteor template each loop?

meteor >= 1.2

Spacebars gained a lot of functionality in 1.2, including a native @index. Helpers are no longer needed to solve this problem - you can simply do this:

{{#each getArray}}
<div class="item" data-value="{{@index}}">{{this}}</div>
{{/each}}

or, if you want to use the index inside a helper:

{{#each getArray}}
<div class="item" data-value="{{someHelper @index}}">{{this}}</div>
{{/each}}

meteor < 1.2

Sometime in the future, spacebars may offer the ability to determine the index directly in the template. However, as of this writing, the only way to get the index is to modify the result returned by the helper. For example you could have getArray return an array of objects which contain a value and an index, like this:

getArray: function() {
var self = this;
self.myArray = self.myArray || [];
return _.map(self.myArray, function(value, index){
return {value: value, index: index};
});
}

And the template could use the index like this:

<template name="someObject">
{{#each getArray}}
<div class="item" data-value="{{index}}">{{value}}</div>
{{/each}}
</template>

Also see this answer for a similar example with cursors.

It's worth mentioning that you probably don't need to store the index in the DOM itself via data-value, unless it's needed by an external plugin. As you can see in the example below, each item has a context with an index value. For more information, see this blog post.

Template.someObject.events({
'click .item': function() {
console.log(this.index);
}
});

How to get the @index of nested #each in meteor

You need to use let to capture the index, like:

{{#let rowIndex=@index}}
{{#each cell in row}}
<div class="cell {{cellState @index rowIndex}}">{{this}}</div>
{{/each}}
{{/let}}

In meteor is there a way to access array index in spacebars

meteor >= 1.2

Spacebars gained a lot of functionality in 1.2, including a native @index. Helpers are no longer needed to solve this problem - you can simply do this:

<template name="showHumans">
<ul>
{{#each humans}}
<li>{{@index}}: {{name}}</li>
{{/each}}
</ul>
</template>

meteor < 1.2

I saw a similar example using template helpers in the meteor book in the "animations" chapter. You can apply a map to the humans cursor in order to add an index like so:

Template.showHumans.helpers({
humans: function() {
return Humans.find({}, {sort: {hotness: -1}}).map(function(human, index) {
human.rank = index;
return human;
});
}
});
<template name="showHumans">
<ul>
{{#each humans}}
<li>{{rank}}: {{name}}</li>
{{/each}}
</ul>
</template>

Iterate For loop in meteor template

Okay, finally I figured it out. Here are the codes:

//example data
var grid = [
{
x:10,
y:20,
title:"first block"
.....
},
....
];
Template.grid.helpers({
grid : function(){
var x = grid[0].x;
var y = grid[0].y;
var row = [];
var num = 1; // for the increment number
for (i = 1; i <= x; i++){
row[i] = [];//let every row has it own array
for(c = 1; c <= y; c++){
row[i].push(num);//add the increment number into each row
num++;

}
}
return row;
}
});

And in the html template:

{{#each row in grid}}
<ul class="row-{{@index}}">
{{#each num in row}}
<li><span class="col-{{num}}">{{num}}</span></li>
{{/each}}
</ul>
{{/each}}

Note that the @index is for getting the array index. And it is only works in meteor >= 1.2 version.

Multiple each index on Meteor Blaze

Huumm, News about Blaze allow new to create variable (with #let). An easy solution is:

let objects = [{name: 'John', age: 18}, {name: 'Foo', age: 25}, {name: 'Bar', age: 35}]
let attrs = ['name', 'age']

{{#each objects}}
{{#let object=this object_idx=@index}}
<h3>Object {{object_idx}}</h3>

{{#each attrs}}
Object idx {{object_idx}} | Object {{object}}
Attr idx {{@index}} | Attr {{this}}
{{/each}}

{{/let}}
{{/each}}

Updated: You can even do {{#each object in objects}} since a while, avoid you to do {{#let object=this}}

{{#each object in objects}}
{{#let object_idx=@index}}
<h3>Object {{object_idx}}</h3>

{{#each attr in attrs}}
Object idx {{object_idx}} | Object {{object}}
Attr idx {{@index}} | Attr {{attr}}
{{/each}}

{{/let}}
{{/each}}

Print the loop index in Meteor.js templates

You can't do this at the moment without giving in an index in your helper, i.e

Template.yourtemplatename.object_with_index = function() {
var objects = Template.yourtemplatename.objects();

for(var i = 0; i=objects.length; i++) {
objects[i].index = i;
}

return objects;
}

Then do:

{{#each object_with_index}}
<p>This is number {{index}}</p>
{{/each}}

Not the prettiest way, but other variations would basically do the same thing under the hood (e.g if you used a map)

Meteor blaze select a specific item by the array index

I'm afraid there is not yet a standard way to do this, however you can write a helper that maps your array to a list of index / value pairs and iterate over it to display what you want.

JS

Template.myTemplate.helpers({
myArrayWithIndex: function(){
return _.map(this.myArray,function(value,index){
return {
index:index,
value:value
};
});
}
});

HTML

<template name="myTemplate">
{{#each myArrayWithIndex}}
myArray[{{index}}] == {{value}}
{{/each}}
</template>

You could also define your own block helper called {{#eachWithIndex}} that would automate this process.



Related Topics



Leave a reply



Submit