0
votes

I'm trying to populate a select element with option elements using Meteor TemplateHelpers and Handlebars.

Template

<template name="newTransaction">
...
<select name="productNameSelect">
{{{ getProductOptions }}} 
</select>
...
</template>

Helper

Template.newTransaction.getProductOptions = function () {
    //Get all products for drop-down
    var count = 0;
    var optionsHTML = "";
    var options = ProductCollection.find({});
    options.forEach( function( product )
    {
      var newOption = "<option value='" + product.productID + "' >" + product.name + "</option>";
      optionsHTML += newOption;
      ++count;
      if( count == options.count() )
      {
        console.log("Products returned for client:" + optionsHTML )
        return optionsHTML;
      }
    });
};

In the browser JavaScript console the correct console log text is printed, but no options in my select list are added to the DOM.

All my other little helper functions work properly, though they are much simpler and might not take as much time. How do I render the option elements correctly?

1

1 Answers

1
votes

This is because of the forEach iterator you've used. When you return the callback, its returned to the forEach iteration and not the helper as you intended.

You need to also remember with Meteor there will be a natural delay as the html and js load first, followed by the data very shortly after.

You could still use forEach but ensure you return data after the loop and not in it. I'm not 100% sure of your intentions so this may not work as you intend but you

var options = ProductCollection.find({});
var html = "";    

options.forEach( function( product )
{
  var newOption = "<option value='" + product.productID + "' >" + product.name + "</option>";
  optionsHTML += newOption;
});

return optionsHTML;

Also dont forget to use three mustaches {{{getProductOptions}}} and not two since you're providing back raw HTML

Also have you considered using an {{each}} loop?

Template.newTransaction.getProductOptions = function () { return ProductCollection.find() }

then you could do this in your html instead

{{#each getProductOptions}}
    <option value="{{productID}}">{{name}}</option>
{{/each}}