0
votes

I do not know where to define the context (JSON object) in a Handlebars.registerHelper function in a Backbone View.

I am able to render my helper function data in the console when I access it through $.getJSON, but I cannot get the data from the helper function into my template:

var SurveyView = Backbone.View.extend({

template: Handlebars.compile(

    '<ul>' + 

    '{{#each models}}<h3>{{attributes.name}}</h3><h4>{{attributes.question}}</h4>'+
    '<li>{{#answerList info}} {{{answers}}}{{/answerList}}</li>{{/each}}' +
    '</ul>' +
    '<button type="button" class="btn btn-danger">Next</button>' +

),

helperOne: function() {
    Handlebars.registerHelper('answerList', function(context, options) {
        var output = "";
        $.getJSON('questions', function(info) {             
            for (var i = 0; i<info.length; i++ ){
                var infos = info[i];
                for (key in infos.answers) {
                    if(infos.answers.hasOwnProperty(key)) {
                             output += '<li>' +
                    '">' + info[i].answers[key] + 
                    '</li>';
                    console.log(output);

                    }
                }
            } 

        });

        return output;  
    }); //end register      
}, 

initialize: function() {
    this.listenTo(this.collection, "reset", this.render);
},


render: function () {
    this.helperOne();
    this.$el.html(this.template(this.collection));
    return this;
}

});

1

1 Answers

1
votes

Trying to do an AJAX call inside a Handlebars helper isn't a very productive thing to do. The helper only knows about text: the helper returns a piece of text that will probably become a set of DOM nodes but there is no way for the helper to know what the DOM nodes are so it can't update anything on the page when the AJAX call returns from the server.

You need to turn your logic around:

  1. Figure out what AJAX calls need to be made.
  2. Perform the AJAX calls.
  3. When all the AJAX calls have finished, collect up the data for the template and hand it to the compiled template function.
  4. Add the template function's return value to the DOM.

In your case, you can get rid of helperOne completely. Then, presumably you'd have an Answer Backbone model and an AnswerList collection which contains Answers. Somewhere you'd do a fetch on the AnswerList and when that returns, you can update your view.