1
votes

I've got a handlebars helper method which is fetching a json object through ajax and I then want to format that json into html and inject it into the template.

I build the html and output to the console, and see the output properly, but
the result of the handlebars helper never gets displayed in the template.

Handlebars.registerHelper("accounts_dropdown", function() {
    function get_dropdown(callback){
    var dropdown='Select Account';

    $.ajax({
        url: 'accounts',
        success: function(response){
            for(var i=0;i<response.length;i++){
            dropdown+=' < option value="'+response[i].id+'">'+response[i].name+'</option>';
                }

            callback(dropdown);
            }
        });
    }

    get_dropdown(function(dropdown){
        console.log(dropdown);
        return new Handlebars.SafeString(dropdown);
    });
  });

and in my template I have


 {{accounts_dropdown}}

2
Is there some copy/paste error with your example? Your for loop is all mangled and apparently missing the json->html code you referred to.Jake Feasel
Sorry @jake, I forgot to format my html tags, that's why it wasn't showing up properly.pedalpete

2 Answers

5
votes

This isn't going to work, because you are loading the dropdown asynchronously. Your helper function needs to return a value for Handlebars to insert into the template, but your helper isn't actually returning anything. One option would be to load it synchronously, like so:

Handlebars.registerHelper("accounts_dropdown", function() {
function get_dropdown(){
 var dropdown='Select Account';

 $.ajax({
    url: 'accounts',
    async: false,
    success: function(response){
        for(var i=0;i<response.length;i++){
        dropdown+=' < option value="'+response[i].id+'">'+response[i].name+'</option>';
            }
        }
    });

 return dropdown;
}

return new Handlebars.SafeString(get_dropdown());
});
1
votes

I'm a bit laste to the party, but I just had a similar problem and found a solution on my own.

Just let the helper return a div with a random/unique id and have the ajax callback insert the response into it.

var id = 'my-async-template-' + Math.floor(Math.random() * 11);

$.ajax({
  url: 'accounts',
  async: false,
  success: function(response){
     $('#' + id).html(response);
});

return '<div id="' + id + '"></div>';
}

Of course, to make it work with OP's exact problem you'd need to generate the entire html block on the server or do some more JavaScript to inject the options into the dropdown.

EDIT:

On second thought, you'll introduce a race condition if you do it that way, so be sure to defer tha ajax call to until after handlebars has finished its job