Ajax request in Backbone View render function

11,221

You are correct in your assumption. It will not render correctly.

The simple fix

Just like the more general case, you can perform the actual rendering inside the success callback.

 render: function(){
        var newObject = this.model.toJSON();
        var that = this; // to fix that `this` refers to in the callback
        $.ajax({
            url:"/user",
            success:function(result){
                newObject.twittername = result.name; ;
                that.$el.html(that.template(newObject));
            }
        });
    }

The better fix

What I'd do is:

  • Have the twitter name as a part of the model
  • fetch it from the model (maybe even with a restful .fetch
  • listen to change events in the view, and call render on such events.

This is because the view should not be responsible for changing model data in Backbone. It's mixing "business logic" with presentation and it can get ugly pretty fast.

[I think this example 2 from Addy Osmani's "Backbone Fundamentals" should give you a general idea on how this sort of structure is laid out.

Share:
11,221
s_curry_s
Author by

s_curry_s

Updated on June 04, 2022

Comments

  • s_curry_s
    s_curry_s almost 2 years

    I want to pass an extra variable (the userid) with before rendering my backbone view. I am getting the the extra variable with a ajax request but because is asynchronous I think my page is being rendered before I get the variable. For simplicity lets say I have this in my backbone view :

    PostsApp.Views.Post = Backbone.View.extend({
        template: _.template($('#post-template').html()),
    
        render: function(){
            var newObject = this.model.toJSON();
            $.ajax({
                url:"/user",
                success:function(result){
                    newObject.twittername = result.name; ;
                }
            });
            this.$el.html(this.template(newObject));
        }
    
    });
    

    I guess I can put this.$el.html(this.template(newObject)); in the callback but than 'this'refers to something else.. Can anyone think of a work around for this?

    Or is it completely very bad to send such a request in the render function..