14

Say I have JSON:

{
userinput: [
    {name: "brian", "value": "i like pies"},
    {name: "susan", "value": "memes are stupid"}
],
feedback: [
    {value: "i also like pies"},
    {value: "null"}
]
}

And I'm trying to draw a table like this:

name ..... | input ......   | feedback
-----------|----------------|-----------------
brian      | I like pies    | I also like pies
susan      | mems are stupid| null

And while I recognise that it would be better to have feedback as a value of "userinput", what I have is not done like that ...

I'm trying to get the index of feedback inside {{#each userinput}}`, e.g.

{{#each userinput}}
<td>{{name}}</td><td>{{value}}</td><td>{{../feedback[@index].value}}</td>
{{/each}}

But of course {{../feedback[@index].value}} does not work.

What is the best way (without changing the structure of the json) to grab the value of the matching index inside the feedback array?

2
  • Hey frumbert, I noticed you haven't selected an answer. Just wanted to point out that, while @Rubens Mariuzzo didn't work for me, nickgraef 's answer did. Commented Nov 24, 2015 at 18:59
  • 1
    @D.Tate at the time I was unable to upgrade handlebars since it used some javascript techniques that were too new for the javascript server side engine I was using; the version I had then didn't contain a lookup helper/method and did something like stackoverflow.com/a/18169209/1238884. Commented Nov 25, 2015 at 3:59

2 Answers 2

15

This can be accomplished using the lookup helper:

The lookup helper allows for dynamic parameter resolution using Handlebars variables. This is useful for resolving values for array indexes.

So the template for your example would look like this:

{{#each userinput}}
    <td>{{name}}</td>
    <td>{{value}}</td>
    <td>
        {{#with (lookup ../feedback @index)}}
            {{value}}
        {{/with}}
    </td>
{{/each}}
Sign up to request clarification or add additional context in comments.

3 Comments

This seems to be the best answer! Works nicely for me! Thanks @nickgraef.
This is the best answer. Works like a charm.
../ path segment is not obvious, but important here if "feedback" is from outside scope. See: handlebarsjs.com/guide/expressions.html#path-expressions
3

I guess you will have to write a block helper for this, as it seems @index can only be used as a stand-alone.

I modified the "list" example, to allow a template like this: "{{#list userinput feedback}}<td>{{name}}</td><td>{{value}}</td><td>{{@feedback.value}}</td>{{/list}}". The implementation is like this, accepting two parameters "input" and "feedback" (plus the standard "options").

Handlebars.registerHelper('list', function(input, feedback, options) {
  var out = "", data;

  // iterate over the input
  for (var i=0; i<input.length; i++) {
    if (options.data) {
      data = Handlebars.createFrame(options.data || {});

      // add "feedback" item to the current frame's data
      data.feedback = feedback[i];
    }

    out += "<tr>" + options.fn(input[i], { data: data }) + "</tr>";
  }

  return out;
});

Here's the Fiddle.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.