Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handlebars If-Else If-Else With String Equality Function

HandlebarsJS doesn't support string equality ('==') so I have to write my own helper, but this answer isn't clear:

https://stackoverflow.com/a/15095019/1005607

Handlebars.registerHelper('if_eq', function(a, b, opts) {
    if(a == b) // Or === depending on your needs
        return opts.fn(this);
    else
        return opts.inverse(this);
});

and then adjust your template:

{{#if_eq this "some message"}}
    ...
{{else}}
    ...
{{/if_eq}}

1) Why is he doing {{#if_eq ..}} rather than {{#if if_eq .. }} ?

2) I also need to do ELSE-IF, which is supported since Handlebars 3.0.0 (I have 4.0). But using his notation, I wouldn't be able to do {{#elseif_eq}} there is no such expression. How would I implement an ELSE-IF with this custom helper?

like image 510
gene b. Avatar asked Dec 06 '17 19:12

gene b.


1 Answers

The helper in your example is a block helper. The helper is aptly named if_eq because it takes two expressions and, if those expressions are equal, it renders what is in the block. The return opts.inverse(this); line does the job of rendering the else block if the expressions are not equal (see: http://handlebarsjs.com/block_helpers.html#conditionals).

If you want to be able to chain else if conditionals in your template, then you cannot use a custom block helper. Instead you must use a regular (non-block) Handlebars helper. Whereas a block helper will render a block of template, a regular helper will return a value. In your case, we would return a Boolean indicating whether or not all arguments are equal. Such a helper could look like the following:

Handlebars.registerHelper('eq', function () {
    const args = Array.prototype.slice.call(arguments, 0, -1);
    return args.every(function (expression) {
        return args[0] === expression;
    });
});

You would use this helper in your template in the following manner:

{{#if (eq val1 val2)}}
    <p>IF Branch</p>
{{else if (eq val2 val3)}}
    <p>ELSE IF Branch</p>
{{else}}
    <p>ELSE Branch</p>
{{/if}}

Please note the parentheses as in the code (eq val1 val2). These parentheses are required because our eq evaluation is a subexpression within the #if expression. The parentheses tell Handlebars to pass the result of the equality check to the #if block helper.

I have created a JS Fiddle for your reference.

Update

The answer above states that you cannot chain block helpers using else if. This is misleading. In fact, if is itself a block helper; and arbitrarily many if blocks can be chained together by using the else keyword. Even different block helpers can be chained in this way.

The important point to address the poster's first question is that two block helpers cannot be used within the same mustache. That is, {{#if if_eq ... }} is invalid if if_eq is a block helper. However, it would be perfectly valid to use if_eq as in the following:

{{#if_eq this 'some message'}}
    <p>If branch.</p>
{{else if_eq this 'some other message'}}
    <p>Else if branch.</p>
{{else}}
    <p>Else branch.</p>
{{/if_eq}}

Please see this fiddle for an example.

like image 72
76484 Avatar answered Sep 30 '22 06:09

76484