When is the right time to fetch a collection in Backbone js?
backbone-views, backbone.js
Solution
The problem in your code is that your `campaignListView` fetch the collection when it is initialized and it is initialized only once. Your `render` method which is actually called from the router doesn't call your `initialize` method of campaignListView, when you change the`url` your second time.
You have two options here :
1. return the class not the instance of your campaignListView and initialize it in the router :
// in your router code
showCampaigns: function(){
var campaignListViewInstance = new campaignListView(); // don't forget the brackets after your initialize function
campaignListViewInstance.render();
},
// in your campaignListView code :
return campaignListView; // without "new"
This will initialize the code everytime the router is hit.
2. place your fetch in the render method
// in your campaignListView code :
initialize:function(){
this.collection = campaignsCollection;
},
render: function(){
this.collection.fetch({success: function(collection) {
var data = {
campaigns: collection,
_: _
};
$('#container').html('Campaigns length: '+data.campaigns.models.length);
}); // this will be fetched everytime you render and also it has success callback
}
Also be aware that you should replace all your instance creating functions with brackets at the end
return new campaignListView; --> return new campaignListView();
return new campaignsCollection; --> return new campaignsCollection();
Another problem you will face is the async work of `fetch`. You should use success or event driven rendering of your collection, because `fetch` works in the background and you will have no data when you immediately call render after calling `fetch`.
+1 for your AMD approach.
Problem
So I'm working on a backbone app, and trying to modularize things as much as I can using require.js. This has been my guide. I'm having trouble getting my view to always fetch my collection. If I access my app from the base url (`myapp.com/`), and go to the route of my view, the collection is fetched. If I do not go to the view, and instead access it from `myapp.com/#/campaigns`, then the collection is not fetched. Here is some relevant code. router.js ``` define([ 'jQuery', 'Underscore', 'Backbone', 'views/home/main', 'views/campaigns/list' ], function($, _, Backbone, mainHomeView, campaignListView ){ var AppRouter = Backbone.Router.extend({ routes: { // Define some URL routes 'campaigns': 'showCampaigns', // Default '*actions': 'defaultAction' }, showCampaigns: function(){ campaignListView.render(); }, defaultAction: function(actions){ // We have no matching route, lets display the home page //mainHomeView.render(); } }); var initialize = function(){ var app_router = new AppRouter; Backbone.history.start(); }; return { initialize: initialize }; }); ``` collections/campaigns.js ``` define([ 'jQuery', 'Underscore', 'Backbone', 'models/campaigns' ], function($, _, Backbone, campaignsModel){ var campaignsCollection = Backbone.Collection.extend({ model: campaignsModel, url: '/campaigns', initialize: function(){ } }); return new campaignsCollection; }); ``` views/campaigns/list.js ``` define([ 'jQuery', 'Underscore', 'Backbone', 'collections/campaigns' ], function($, _, Backbone, campaignsCollection){ var campaignListView = Backbone.View.extend({ el:$('#container'), initialize:function(){ this.collection = campaignsCollection; this.collection.fetch(); }, render: function(){ var data = { campaigns: this.collection, _: _ }; $('#container').html('Campaigns length: '+data.campaigns.models.length); } }); return new campaignListView; }); ``` Any ideas on what I'm doing wrong? I believe it has something to do with calling `this.collection.fetch()` in the `initalize` function of the view. If that is the issue, where should I put `fetch()`?