public
Last active

Handlebars.js helpers to iterate over objects

  • Download Gist
handlebars.object_helpers.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
// HELPER: #key_value
//
// Usage: {{#key_value obj}} Key: {{key}} // Value: {{value}} {{/key_value}}
//
// Iterate over an object, setting 'key' and 'value' for each property in
// the object.
Handlebars.registerHelper("key_value", function(obj, fn) {
var buffer = "",
key;
 
for (key in obj) {
if (obj.hasOwnProperty(key)) {
buffer += fn({key: key, value: obj[key]});
}
}
 
return buffer;
});
 
// HELPER: #each_with_key
//
// Usage: {{#each_with_key container key="myKey"}}...{{/each_with_key}}
//
// Iterate over an object containing other objects. Each
// inner object will be used in turn, with an added key ("myKey")
// set to the value of the inner object's key in the container.
Handlebars.registerHelper("each_with_key", function(obj, fn) {
var context,
buffer = "",
key,
keyName = fn.hash.key;
 
for (key in obj) {
if (obj.hasOwnProperty(key)) {
context = obj[key];
 
if (keyName) {
context[keyName] = key;
}
 
buffer += fn(context);
}
}
 
return buffer;
});

This is a helper that really should be apart of the Handlebars core API.

This is a helper that really should be apart of the Handlebars core API.

I think that starting from 2.x release, callback should be function(obj, options) and instead of fn(), one should use options.fn()

I made those changes in a fork and it is now working for me. I agree it should be included in handlebars core API.

Agree with pdeschen, the code in this gist is buggy and that's how I fixed it too.

Great helper! should be included in core.

Thanks strathmeyer

Coffeescript version of key_value which worked for me:

Handlebars.registerHelper 'key_value', (obj, hash) ->
  buffer = ""

  for key of obj
    if obj.hasOwnProperty(key)
      buffer += hash.fn({ key: key, value: obj[key] })

  buffer

@kowal You can simplify that code a bit:

Handlebars.registerHelper 'key_value', (obj, hash) ->
  buffer = ""

  for own key, value of obj
      buffer += hash.fn({ key, value })

  buffer

In the case of there being an empty string template between the key_value tag pair, this will output undefined for each property in the object being iterated. I think it is best practice to avoid this, and it can be done by defaulting to an empty string if the return of hash.fn({ key, value }) is falsey. See below:

CS

Handlebars.registerHelper 'key_value', (obj, hash) ->
  buffer = ""

  for own key, value of obj
      buffer += hash.fn({ key, value }) || ''

  buffer

JS

Handlebars.registerHelper('key_value', function (obj, hash) {
    var buffer, key, value;
    buffer = "";
    for (key in obj) {
        if (!Object.hasOwnProperty.call(obj, key)) {
            continue;
        }
        buffer += hash.fn({
            key: key,
            value: obj[key]
        }) || '';
    }
    return buffer;
});

This is a helper that really should be apart of the Handlebars core API.

@calidion it is, For object iteration, use {{@key}} instead:
{{#each object}}
{{@key}}: {{this}}
{{/each}}

Handlebars now supports looping objects, but as far as i know ember does not

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.