javascriptjqueryhtmlhandlebars.jshandlebarshelper

Change/update a variable in Handlebars JS from the parent context inside a loop


I've seen many examples of how to access a variable which belongs to the parent context inside a loop. However, I need to not only access the variable but change/update it as well.

As you can see below, I have a custom helper that sets a variable, but I when try to change that variable inside the loop, it does not work. Is there a way to make it work?

Please take a look at this jsFiddle.

Template

{{setVarWithName "test" "hello"}}
{{#each questions}}
    <h3>{{title}}</h3>
    <p>before update: {{../test}}</p>
    {{setVarWithName "test" "goodbye"}}
    <p>after update: {{../test}}</p>
    <hr />
{{/each}}

Handlebars init with helper

var source = $("#template").html(); 
var template = Handlebars.compile(source); 

var data = {
  "questions": [
     {"title": "Question 1"},
     {"title": "Question 2"}
   ]
}; 

Handlebars.registerHelper('setVarWithName', function (name, value) {
    this[name] = value;
    return '';
});

$('body').append(template(data));

Solution

  • The answer, like often in JavaScript, is the scope. Basically, this inside of your helper setVarWithName does not point into your data variable when used inside of {{#each}} loop, but it does point into the question[@index]. What you need to do:

    var source = $("#template").html(); 
    var template = Handlebars.compile(source); 
    
    var data = {
      "questions": [
         {"title": "Question 1"},
         {"title": "Question 2"}
       ]
    }; 
    
    Handlebars.registerHelper('setVarWithName', function (name, value) {
        data[name] = value; // changed from this to data
        return '';
    });
    
    $('body').append(template(data));
    

    See my working fiddle. I added {{s}} helper to print rendered this into the template for readability.