Useful stackoverflow question about how I had originally set it up: http://stackoverflow.com/questions/27722019/backbonejs-collection-not-populated-but-fetch-works
The issue comes when using json as its async and the collection hasn’t been populated by the time the view is instantiated. We need to bind sync to the view and only call fetch after the view has been instantiated.
The over view of the set up is as such:
It’s a work in progress but here I am so far:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Results App Training</title> <script src="js/libs/jquery.js"></script> <script src="js/libs/underscore.js"></script> <script src="js/libs/backbone.js"></script> <script type="text/javascript"> $( document ).ready(function() { /* *********** Models *********** */ var MatchInfo = Backbone.Model.extend({ defaults: { season:"1415" } });//model class var matchInfo = new MatchInfo(); //model instance /* *********** Collections *********** */ var Matches = Backbone.Collection.extend({ model: MatchInfo, //note this references the model class, not the model instance url : "http://www.hookhockey.com/index.php/temp-gillian/", sync : function(method, collection, options) { // By setting the dataType to "jsonp", jQuery creates a function // and adds it as a callback parameter to the request, e.g.: // [url]&callback=jQuery19104472605645155031_1373700330157&q=bananarama // If you want another name for the callback, also specify the // jsonpCallback option. // After this function is called (by the JSONP response), the script tag // is removed and the parse method is called, just as it would be // when AJAX was used. //console.log('sync'); options.dataType = "jsonp"; return Backbone.sync(method, collection, options); }, parse : function(response) { // console.log(response.matches); //.matches is what the json at http://www.hookhockey.com/index.php/temp-gillian/ is putting out return response.matches; } }); //collection class var matches = new Matches(); //collection instance /* *********** Views *********** */ //model view var MatchModelView = Backbone.View.extend({ tagName: 'li', template: _.template( $("#matchTemplate").html() ), // removed because template was not being found - uses underscore and the content from index.html script tag with the id of matchElement that contains the template tags initialize: function () { }, render: function() { var matchTemplate = this.template(this.model.toJSON()); //passes in all of the model data (using this.model.toJSON()) into the template (this.template) so that info is available to the template tags //var matchTemplate = '<p>' + this.model.get('title') + '</p>'; this.$el.html(matchTemplate); //pass the templated info into the el element and return it for render return this; } }); //model view class //var matchModelView = new MatchModelView({model:matchInfo}); //model view instance //console.log(matchModelView.render().el); //collection view class var MatchesModelView = Backbone.View.extend({ tagName: 'ul', initialize: function () { _.bindAll(this, "render"); this.collection.bind("reset", this.render); }, render: function(){ console.log('collection length in view:' + this.collection.length); //returns 0 this.collection.each(this.oneMatch, this); return this; }, oneMatch: function (aMatch){ //console.log(aMatch); var matchView = new MatchModelView ({ model: aMatch }); this.$el.append(matchView.render().el); } }); var matchesModelView = new MatchesModelView({collection: matches }); /* Fetching */ //render should be called on the view after it has been instantiated matches.bind("sync", matchesModelView.render, matches); matches.fetch({ success : function(collection, response, options) { /* notes: calling these outside of the success listener meant that nothing got returned. This is because they fire before the fetch returns http://stackoverflow.com/questions/9431673/load-data-into-a-backbone-collection-from-json-file the alternative is to call them within the success function or to call them like so: .complete(function() { console.log(matches); console.log('length: ' + matches.length); }); ..after the fetch call. */ console.log('in collection instance fetch success: ' + matches.length); return response.matches; }, error : function(collection, response, options) { console.log(response.statusText); }, // A timeout is the only way to get an error event for JSONP calls! timeout : 5000 }); /* end fetching */ $("#allMatches").html(matchesModelView.render().el); /* *********** Routers *********** */ }); //end doc ready </script> </head> <body> <div class="site"> <div id="allMatches">adasdasd</div> <div id="copy"></div> </div> <script id="matchTemplate" type="text/template"> <%= title %> </script> </body> </html>