Conditional helper gives syntax error - is this weird?


#1

See the jsfiddle below for a sample code with a sample collection.

http://jsfiddle.net/xfogcu9v/1/

Let’s say I have some radio buttons generated from the collection. I want to set a selected attribute on the wrapping element that defines the selected radio button. As in my example it would be great of course to retrieve the active entry in the collection like so:

    {{#if active}}
        <paper-radio-group selected="{{content}}">
    {{/if}}

This is not possible however because meteor throws an error of a non-opened tag. I’m assuming this is because meteor assumes that there’s a possibility that there’s no returned active value in the collection array, which would result in the paper-radio-group never being opened. But I know there’s always one value in the array that’s active.

Now I could write my own template handler for this of course but I want to take the time to discuss this. Am I having the wrong thought process of wanting to do it this way? To me it makes perfect sense but to meteor it doesn’t seem to. Any thoughts?

The reason why I find this inconvenient is: Let’s say I have four different collections like this. I’d have to write four different handlers for each of these cases, when I theoretically can retrieve the value already from my HTML template if meteor wouldn’t throw an error.


#2

Spacebars/Blaze can’t handle incomplete snippets of HTML inside block helpers, since the thing it generates is an HTML syntax tree, not an HTML string. For example, you also can’t do this:

<h{{#if stuff}}1{{else}}2{{/if}}>Heading</h{{#if stuff}}1{{else}}2{{/if}}>

The solution is to restructure your code such that you don’t need to do this. Consider the following option:

{{#if active}}
  <paper-radio-group selected="{{content}}">
    {{> insideGroup}}
  </paper-radio-group>
{{else}}
  <div>
    {{> insideGroup}}
  </div>
{{/if}}

I’m not really sure what you are trying to do from your question, but maybe the above is helpful.


#3

I couldn’t get it working the way you wrote it down but I understood what you explained though. However, in the meantime I came up with this, which can take different types of arguments, so it’s just one handler but works for several of my collections. (If anyone ends up using this, note I’m using findOne because I just have one document in this collection right now)

  requirement: function(requirement) {
    var entry = requirement;
    var selectedRequirement = VendorProducts.findOne().requirements[entry];
    var result; 

    function getValue(element, index, array) {
      if( element.active ) {
        result = element.content;
      }
    }

    selectedRequirement.forEach(getValue);
    return result;
  },





<paper-radio-group selected="{{requirement 'bleed'}}">
{{#each products_list}}
    {{#each requirements.bleed}}
        <paper-radio-button name="{{content}}">{{content}}</paper-radio-button>
    {{/each}}
{{/each}}
</paper-radio-group>