280

I'm using Handlebars for templating in my project. Is there a way to get the index of the current iteration of an "each" helper in Handlebars?

<tbody>
     {{#each item}}
         <tr>
            <td><!--HOW TO GET ARRAY INDEX HERE?--></td>
            <td>{{this.key}}</td>
            <td>{{this.value}}</td>
         </tr>
     {{/each}}
</tbody>
Valentin Nemcev
  • 4,650
  • 2
  • 18
  • 20
thunderboltz
  • 3,197
  • 3
  • 18
  • 20
  • 1
    You can register your own helper to do this, for example: https://gist.github.com/1048968 or: http://pastebin.com/ksGrVYkz – stusmith Aug 09 '12 at 13:55
  • 1
    I added another solution to the Gist example that works with handlebars-1.0.rc.1.js. https://gist.github.com/1048968#gistcomment-617934 – mlienau Dec 06 '12 at 22:00

7 Answers7

541

In the newer versions of Handlebars index (or key in the case of object iteration) is provided by default with the standard each helper.


snippet from : https://github.com/wycats/handlebars.js/issues/250#issuecomment-9514811

The index of the current array item has been available for some time now via @index:

{{#each array}}
    {{@index}}: {{this}}
{{/each}}

For object iteration, use @key instead:

{{#each object}}
    {{@key}}: {{this}}
{{/each}} 
Fabrício Matté
  • 65,581
  • 23
  • 120
  • 159
ro60
  • 5,434
  • 1
  • 12
  • 5
  • 57
    I have tried to implement this in various situations, every single time I get a error on the console. `Uncaught SyntaxError: Unexpected token ,` – waltfy Jul 19 '13 at 10:45
  • 1
    This works fine but make sure the '@' character is escaped if you use a web framework where @ has a special meaning :) – AlexG Jan 07 '14 at 16:29
  • I'm having the same issue in rails with .hbs files. Not aware of how to escape the @ char is this environment? – Alexandros K Jan 28 '14 at 15:57
  • 7
    It's worth noting that as of [v1.2.0](http://github.com/wycats/handlebars.js/blob/master/release-notes.md#v120---december-23rd-2013), `@index` and `@first` are now supported for each iteration on objects too. – WynandB Feb 13 '14 at 00:24
  • 7
    If you're using ASP.Net MVC Razor you escape with @@, i.e. `{{@@index}}` – masty May 13 '14 at 23:49
  • 2
    [Solve `Uncaught SyntaxError: Unexpected token ,`](http://stackoverflow.com/questions/21841340/what-is-the-correct-way-of-getting-the-index-of-an-array-when-iterating-over-it) – Mark Fu May 19 '14 at 15:39
  • You can mix this with the `if` or `unless` helpers to do things like add a separator after the first item, e.g. `{{#if @@index}}
    {{/if}}`
    – jocull Oct 04 '16 at 20:31
  • Any idea how I would get the index or key in Framework7 virtualList itemTemplate looper? I know it iterates an items object and uses handlebars. Can't find this documented anywhere. – juliusbangert Mar 08 '18 at 14:32
  • how would you get a value from a previous item in the each helper? ie array(@index-1).date. Trying to check current date versus previous items. – v3nt Nov 04 '20 at 09:54
18

This has changed in the newer versions of Ember.

For arrays:

{{#each array}}
    {{_view.contentIndex}}: {{this}}
{{/each}}

It looks like the #each block no longer works on objects. My suggestion is to roll your own helper function for it.

Thanks for this tip.

Community
  • 1
  • 1
Ryan H Lewis
  • 614
  • 8
  • 5
14

I know this is too late. But i solved this issue with following Code:

Java Script:

Handlebars.registerHelper('eachData', function(context, options) {
      var fn = options.fn, inverse = options.inverse, ctx;
      var ret = "";

      if(context && context.length > 0) {
        for(var i=0, j=context.length; i<j; i++) {
          ctx = Object.create(context[i]);
          ctx.index = i;
          ret = ret + fn(ctx);
        }
      } else {
        ret = inverse(this);
      }
      return ret;
}); 

HTML:

{{#eachData items}}
 {{index}} // You got here start with 0 index
{{/eachData}}

if you want start your index with 1 you should do following code:

Javascript:

Handlebars.registerHelper('eachData', function(context, options) {
      var fn = options.fn, inverse = options.inverse, ctx;
      var ret = "";

      if(context && context.length > 0) {
        for(var i=0, j=context.length; i<j; i++) {
          ctx = Object.create(context[i]);
          ctx.index = i;
          ret = ret + fn(ctx);
        }
      } else {
        ret = inverse(this);
      }
      return ret;
    }); 

Handlebars.registerHelper("math", function(lvalue, operator, rvalue, options) {
    lvalue = parseFloat(lvalue);
    rvalue = parseFloat(rvalue);

    return {
        "+": lvalue + rvalue
    }[operator];
});

HTML:

{{#eachData items}}
     {{math index "+" 1}} // You got here start with 1 index
 {{/eachData}}

Thanks.

Naitik
  • 1,426
  • 15
  • 26
  • 1
    Thanks, you clarified that @index starts at 0, and provided a method to change it to 1 based index. Exactly what I needed. – Rebs Apr 11 '17 at 00:43
14

In handlebar version 3.0 onwards,

{{#each users as |user userId|}}
  Id: {{userId}} Name: {{user.name}}
{{/each}}

In this particular example, user will have the same value as the current context and userId will have the index value for the iteration. Refer - http://handlebarsjs.com/block_helpers.html in block helpers section

Ember Freak
  • 12,538
  • 3
  • 20
  • 47
7

Arrays:

{{#each array}}
    {{@index}}: {{this}}
{{/each}}

If you have arrays of objects... you can iterate through the children:

{{#each array}}
    //each this = { key: value, key: value, ...}
    {{#each this}}
        //each key=@key and value=this of child object 
        {{@key}}: {{this}}
        //Or get index number of parent array looping
        {{@../index}}
    {{/each}}
{{/each}}

Objects:

{{#each object}}
    {{@key}}: {{this}}
{{/each}} 

If you have nested objects you can access the key of parent object with {{@../key}}

RegarBoy
  • 2,234
  • 15
  • 36
0

In handlebar version 4.0 onwards,

{{#list array}}
  {{@index}} 
{{/list}}
anonymous
  • 992
  • 1
  • 9
  • 25
0

Using loop in hbs little bit complex

<tbody>
     {{#each item}}
         <tr>
            <td><!--HOW TO GET ARRAY INDEX HERE?--></td>
            <td>{{@index}}</td>
            <td>{{this}}</td>
         </tr>
     {{/each}}
</tbody>

Learn more

MD SHAYON
  • 2,833
  • 21
  • 18