61

How to access parent @index value in each-loop?

Tried the following:

{{#each company}}
{{#each employee}}
  {{../@index}} // how to access company index here?
{{/each}}
{{/each}}

This results to an error:

Expecting 'ID', got 'DATA'

Fdr
  • 3,726
  • 5
  • 27
  • 41

5 Answers5

101

There is a syntax error in the example. The correct syntax is {{@../index}}.

We are looking at ways that we can support custom naming of these parameters in future versions of the language so this is easier to deal with. https://github.com/wycats/handlebars.js/issues/907

Kevin Decker
  • 2,235
  • 1
  • 17
  • 17
28

This worked for me:

{{#each company}}
{{setIndex @index}}
{{#each employee}}
  {{../index}}
{{/each}}
{{/each}}

JS:

Handlebars.registerHelper('setIndex', function(value){
    this.index = Number(value + 1); //I needed human readable index, not zero based
});

Just make sure the company object doesn't have index property.

strah
  • 6,702
  • 4
  • 33
  • 45
  • 1
    Sadly this doesn't seem to work if the inner loop is rendered from a template: ``{{>my-template}}`` yields ``Cannot read property 'index' of undefined``. Do you know a solution for that? – Lincoln Apr 24 '13 at 12:09
  • 1
    @Lincoln you can try the suggestions here http://stackoverflow.com/a/18026063/271442 - I went for the include helper approach. – mynameistechno Jan 29 '14 at 16:33
  • This is an awesome trick. I will share a jsfiddle link. Thanks! – Karthik Sankar May 09 '14 at 17:42
  • 1
    Here is an extensible version that allows you to set a hash of key/value pairs: http://jsfiddle.net/gfullam/Dc35g/ Example using subexpression: `{{set index=@index indexPlus1=(math @index "+" 1)}}` – gfullam Jul 10 '14 at 14:33
15

Answer: {{@../index}}

From the Handlebars docs (see bottom of 'each' helper section):

"Nested each blocks may access the interation variables via depted paths. To access the parent index, for example, {{@../index}} can be used."

NOTE: I'm using v1.3 so it's at least that old.

REMINDER: Helpers are your last best option. 9/10 there is a better solution.

jordanb
  • 1,975
  • 17
  • 8
6

It looks like there's a new syntax in Ember v2.2.0. I tried all the answers here and they didn't work for me.

What I found worked was naming the parent loop's index and the child loop's index.

{{#each parents as |parent parentIndex|}}
    {{parentIndex}}
    {{#each children as |child childIndex|}}
        {{parentIndex}}
        {{childIndex}}
    {{/each}}
{{/each}}
Andrew Toy
  • 93
  • 1
  • 5
1

registe an Helper method:

Handlebars.registerHelper('eachWithIndex', function(cursor, options) {
    var fn = options.fn, inverse = options.inverse;
    var ret = "";
    var idx = -1;
    //console.log(cursor);
    cursor.forEach(function(item){
        idx++;
        console.log(item.index);
        item.index = idx;
        ret+=fn(item);
    });
    return ret;
}); 

handlebars template:

{{#eachWithIndex outer}}
  {{#each inner}}
   {{../index}} // access outer index like this. I used hanlebars V1.3.0
   {{index}} // access inner index
  {{/each}}
{{/eachWithIndex}}
Fish
  • 117
  • 2
  • 13