agconti
agconti

Reputation: 18093

Backbone Collection wont render outside of fetch

The problem: My collection fails to render to the page if render method is called out side of a success callback when the collection is fetched.

I have a basic backbone collection that I'm trying to render to my app after it fetches some json from my server. After following a bunch of tutorials I'd expect it would work like this:

var restaurants = new RestaurantsCollection();
var restaurantsView = new RestaurantsView({collection: restaurants});
restaurants.fetch():
$(curate.targets.restaurantApp).append(restaurantsView.render().el);

The collection successfully fetches the json but its never appended to the page.

Alternatively, if I append in the success callback of fetch() it appends to to page fine. Like so:

var restaurants = new RestaurantsCollection();
var restaurantsView = new RestaurantsView({collection: restaurants});
restaurants.fetch({
    success: function(collection){
        console.log(collection);
        $(curate.targets.restaurantApp).append(restaurantsView.render().$el);


    },
    error: function(jqXHR, textStatus, errorThrown){
        alert(errorThrown);
        console.log(jqXHR);
    }
});

RestaurantsView:

var RestaurantsView = Backbone.View.extend({
    el: $(curate.targets.restaurantList),
    initialize: function(){
      this.collection.fetch();
      this.listenTo(this.collection, 'reset', this.render, this);
    },
    render: function(){
      this.addAll();
      return this;
    },
    addAll: function(){
      this.collection.forEach(this.addOne, this);
    },
    addOne: function(RestaurantModel){
      var restaurantView = new RestaurantModelView({model: RestaurantModel});
      this.$el.append(restaurantView.render().el);
    }
});

Is it necessary to append the render and append the view in the success call back of fetch() or is there a better way?

Upvotes: 0

Views: 129

Answers (3)

anAgent
anAgent

Reputation: 2780

You should be able to bind an event on your collection that triggers render on your view - like so:

This assumes the code inside of your RestaurantsView initialize function.

this.collection.on('change', this.render);

Also, the event you're looking for is going to be "sync" rather than "reset". Current source code in 1.0.0 for Backbone will fire a sync event after a fetch.

NOTE: If the server doesn't return any data, "sync" will not be triggered.

Upvotes: 1

Bharathwaaj
Bharathwaaj

Reputation: 2697

Try reordering the lines. Usually all the events to be callbacked are registered first before calling fetch.

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

Upvotes: 0

Dimitri
Dimitri

Reputation: 302

Fetch is getting data from you're server through ajax, you need a callback function after .fetch

Upvotes: 0

Related Questions