335

I am trying to specify the index of an item in an array within a handlebars template:

{
  people: [
    {"name":"Yehuda Katz"},
    {"name":"Luke"},
    {"name":"Naomi"}
  ]
}

using this:

<ul id="luke_should_be_here">
{{people[1].name}}
</ul>

If the above is not possible, how would I write a helper that could access a spefic item within the array?

0

9 Answers 9

466

Try this:

<ul id="luke_should_be_here">
{{people.1.name}}
</ul>
Sign up to request clarification or add additional context in comments.

11 Comments

I'm getting Expecting 'ID' error with {{user.links.websites.1}} or {{user.links.websites.0}}
@OlivierLalonde, I had to use something like {{ websites.[0] }} .
Indeed, @Matt, that is not just some lucky format, but is kind of the documented syntax. (See my answer.)
For ember.js, I had to do something like people.content.1.name
@lukemh A LOT of stuff in handlebars is either poorly documented or not documented anywhere. Yayyyy....
|
382

The following, with an additional dot before the index, works just as expected. Here, the square brackets are optional when the index is followed by another property:

{{people.[1].name}}
{{people.1.name}}

However, the square brackets are required in:

{{#with people.[1]}}
  {{name}}
{{/with}}

In the latter, using the index number without the square brackets would get one:

Error: Parse error on line ...:
...     {{#with people.1}}                
-----------------------^
Expecting 'ID', got 'INTEGER'

As an aside: the brackets are (also) used for segment-literal syntax, to refer to actual identifiers (not index numbers) that would otherwise be invalid. More details in What is a valid identifier?

(Tested with Handlebars in YUI.)

2.xx Update

You can now use the get helper for this:

(get people index)

although if you get an error about index needing to be a string, do:

(get people (concat index ""))

4 Comments

This should be the answer because it is more thorough than the selected answer. Requiring square brackets when the index is at the end had me stuck for a while!
this did the trick! thanks... the chosen answer above this didn't, please mark this as the correct.
The {{#with people.1}} solution worked for me, using com.github.jknack:handlebars:4.1.2.
trying to find a way to adjust the index number so I can check a value from the previous item in the loop against this one. Any ideas?
35
{{#each array}}
  {{@index}}
{{/each}}

2 Comments

Awesome, This is the correct answer. @index will give you the position in the array.
Correct answer, can anybody help me how can I print index starting with 1. By default it starts from 0.
21

If undocumented features aren't your game, the same can be accomplished here:

Handlebars.registerHelper('index_of', function(context,ndx) {
  return context[ndx];
});

Then in a template

{{#index_of this 1}}{{/index_of}}   

I wrote the above before I got a hold of

this.[0]

I can't see one getting too far with handlebars without writing your own helpers.

Comments

18

If you want to use dynamic variables

This won't work:

{{#each obj[key]}}
...
{{/each}}

You need to do:

{{#each (lookup obj key)}}
...
{{/each}}

see handlebars lookup helper and handlebars subexpressions.

1 Comment

lookup worked here, even with an index an list from a previous block : {{lookup ../../btnPercentages @../index}}
10

Please try this, if you want to fetch first/last.

{{#each list}}

    {{#if @first}}
        <div class="active">
    {{else}}
        <div>
    {{/if}}

{{/each}}


{{#each list}}

    {{#if @last}}
        <div class="last-element">
    {{else}}
        <div>
    {{/if}}

{{/each}}

Comments

10

While you are looping in an array with each and if you want to access another array in the context of the current item you do it like this.

Here is the example data.

[
  {
    name: 'foo',
    attr: [ 'boo', 'zoo' ]
  },
  {
    name: 'bar',
    attr: [ 'far', 'zar' ]
  }
]

Here is the handlebars to get the first item in attr array.

{{#each player}}
  <p> {{this.name}} </p>

  {{#with this.attr}}
    <p> {{this.[0]}} </p>
  {{/with}}

{{/each}}

This will output

<p> foo </p>
<p> boo </p>

<p> bar </p>
<p> far </p>

2 Comments

if the attr array has different number of elements for different objects then what will be the process to iterate through it ? for example : [ { name: 'foo', attr: [ 'boo', 'zoo' ] }, { name: 'bar', attr: [ 'far', 'zar','sar ] } ] then how are you going to show all the attr for every objects of the array ?
i didn't try it but i assume in {{#with this.attr}} this would work instead of this.[0]
1

The following syntax can also be used if the array is not named (just the array is passed to the template):

  <ul id="luke_should_be_here">
  {{this.1.name}}
  </ul>

Comments

1

In my case I wanted to access an array inside a custom helper like so,

{{#ifCond arr.[@index] "foo" }}

Which did not work, but the answer suggested by @julesbou worked.

Working code:

{{#ifCond (lookup arr @index) "" }}

Hope this helps! Cheers.

1 Comment

how would you adjust the index value in this case? ie I want to compare a value from index and index - 1 (doesn't work). Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.