Added @index for objects to #each helper. #451

Closed
wants to merge 1 commit into
from

Projects

None yet

6 participants

Currently the @index is only returned when looping through an array with the @each helper. This PR also returns @index when looping through objects as well.

Contributor

When traversing over an object in JavaScript, you're not guaranteed that the properties will be traversed in a particular (or even repeatable) order. The ECMA standard doesn't specify how object properties should be traversed—browsers might traverse them in order of their insertion or in numerical order, and there's variance between different browsers.

What's your use case?

The use case is the same as the use case when using an Array, and could include being able to know when it is the first or last item in the object. It just make sense that Array's have it, but Objects don't.

Contributor

There's no such thing of the "first" or "last" property of an object in JavaScript. Objects in JavaScript are, in a mathematical sense, sets of properties with no intrinsic order. How would you do this with pure JS? (and without writing 2 loops)

@index == 0 == first
@index == object.length == last

@kpdecker kpdecker commented on the diff Apr 7, 2013
spec/qunit_spec.js
@@ -791,6 +791,16 @@ test("each with @index", function() {
equal(result, "0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!", "The @index variable is used");
});
+test("each object with @index", function() {
+ var string = "{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!";
+ var hash = {goodbyes: {one: {text: "goodbye"}, two: {text: "Goodbye"}, three: {text: "GOODBYE"}}, world: "world"};
+
+ var template = CompilerContext.compile(string);
+ var result = template(hash);
+
+ equal(result, "0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!", "The @index variable is used");
kpdecker
kpdecker Apr 7, 2013 Collaborator

Is zero-based the proper thing here? Wouldn't the common use case be to display one-based numbering to the user?

joelmoss
joelmoss Apr 7, 2013

I'm trying to keep it consistent with arrays.

Handlebars doesn't parse @index correctly. Any ideas why?
http://jsbin.com/eqasax/2/edit

sulphur commented Apr 26, 2013

+1

When iterating on objects, what is important is the @index value of the returned object in the loop.

My actual use case to display a clearfix for Bootstrap 3 every 4 items, to ensure a proper line return for various viewport size:

<div class="row">
  {{#each games}}
  <div class="col-sm-3">
    <h2><a href="/games/{{slug}}/">{{title}}</a></h2>
  </div>

  {{#eq @index 4}} <div class="clearfix"></div> {{/eq}}
  {{/each}}
</div>

With :

var games = {
  "barbie-super-model": {
    "title": "Barbie Super Model",
    "reviews_count": 1,
    "rating": 0.5
  },
  "donkey-kong-country-2-diddy-s-kong-quest": {
    "title": "Donkey Kong Country 2 : Diddy's Kong Quest",
    "alternate_titles": [
      "DKC2",
      "DKC II"
    ],
    "editor": "RARE",
    "reviews_count": 1,
    "rating": 5
  }
}
Collaborator

Implemented by #661 which was easier to merge.

@kpdecker kpdecker closed this Dec 23, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment