0

I'm trying to iterate over an array of strings in a handlebars template with builtin helper '{{#each}}'. But it doesn't work.

Simplified example:

A custom helper function which returns an array of strings:

helpers: {
  arr: function () {
    return ['foo', 'bar'];
  }
}

The Template in which to access the helper:

{{#each arr}}
  {{@index}}: {{this}}
{{else}}
  default
{{/each}}

But this always prints the else case. When directly accessing the helper (without #each) it results as expected:

{{arr}} // prints => foo,bar

I somewhere read that #each needs a object to work with. I couldn't find anything about this in context of a helper in the docs - nevertheless I tried to wrap the returning array in an object in several ways. But I wasn't able to make it work.

So, how to properly access an array of strings (which comes from a helper) within a handlebars template?

zwif
  • 195
  • 3
  • 13
  • 1
    If you're doing this for testing purposes or as a playground, simply don't have a helper return an array. Helper is supposed to be applied to a value, it's not meant to return an array that you iterate. Is there a reason why your helper returns an array, except for testing purposes? Is there going to be a case where you'll actually use a helper that gives you arrays that you iterate? – Mjh Oct 02 '17 at 15:00
  • I'm new to handlebars. I'm using [express-handlebars](https://github.com/ericf/express-handlebars) in a node app. My understanding was that one use-case of helpers is to pass information (e.g. an array) from server to client. – zwif Oct 02 '17 at 15:11

1 Answers1

2

The Handlebars documentation on subexpressions states the following:

Handlebars offers support for subexpressions, which allows you to invoke multiple helpers within a single mustache, and pass in the results of inner helper invocations as arguments to outer helpers. Subexpressions are delimited by parentheses. [emphasis added]

What this means is that we need to tell Handlebars that arr is not a property to be looked-up on the context object, but a helper to be invoked, and that we do that by wrapping the inner helper in parentheses:

{{#each (arr)}}

With that said, I would agree with the comment by Mjh, that stated that this is not the correct use of a helper. Your data should be passed directly to your template function for interpolation. The purpose of a helper is to modify some data or to perform some logic on it. A helper function that has no parameters is a pretty pungent code-smell.

76484
  • 8,498
  • 3
  • 19
  • 30