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
How Can Print Preview Be Called from JavaScript
Copy to Clipboard in Chrome Extension
Google Bar Chart Cannot Change Individual Bar Color
Dynamic Extension Context Menu That Depends on Selected Text
Firebase Callable Function + Cors
JavaScript Pass Object as Reference
Moment.Js - Utc Gives Wrong Date
[Vue Warn]: Property or Method Is Not Defined on the Instance But Referenced During Render
Sort Object Properties and JSON.Stringify
Access Microphone from a Browser - JavaScript
Convert Simple Array into Two-Dimensional Array (Matrix)
Find All Text Nodes in HTML Page
Editing in the Chrome Debugger