Search code examples
javascripthandlebars.js

Undefined in Handlebars helper function


I have a custom helper as given below. Somehow value of the passed params (v1, v2, v2) gets undefined. Any pointers would be helpful.

Something.js:

Handlebars.registerHelper('hasAccess', function(v1, v2, v3) {
    console.log(v1 + ', ' + v2 + ', ' + v3); //this gives undefined
    if (v1 && v2 && v3) {
        return true;
    }
    return false;   
});

and my template, as follows:

 {{#each list1}}
    <span>{{this}}{{#if hasAccess value1 value2 value3}}<sup>display-something</sup>{{/if}}</span>
 {{/each}}

getData() {
      const value1 = true;
      let value2 = true;
      let value3 = false;
      let list1 = [10, 20, 30];
   }

I am also new to UI so any suggestion to improve the code would be appreciated.


Solution

  • There are a couple of issues with your template.

    First, #if requires a single argument, which it will evaluate for truthiness. In order to give #if the result of the hasAccess helper, we will need to parens to make the hasAccess evaluation a subexpression.

    Our template gets updated to:

    {{#if (hasAccess value1 value2 value3)}}<sup>display-something</sup>{{/if}}
    

    This prevents Handlebars from throwing an error, but the arguments to our hasAccess helper all have the value of undefined. This is because value1, value2 and value3 are not available to the evaluation context within our #each loop. We will need to use paths in order to access the parent context.

    Now our template becomes:

    {{#if (hasAccess ../value1 ../value2 ../value3)}}<sup>display-something</sup>{{/if}}
    

    Note: As value1, value2 and value3 all belong to our root data context, we could alternatively do:

    {{#if (hasAccess @root.value1 @root.value2 @root.value3)}}<sup>display-something</sup>{{/if}}
    

    I have created a fiddle for your reference.

    As for suggestions on code improvement. I am of the opinion that the if (true) { return true; } style is an anti-pattern and is much more cleanly written as:

    Handlebars.registerHelper('hasAccess', function(v1, v2, v3) {
      return Boolean(v1 && v2 && v3); 
    });