Brent
Brent

Reputation: 2485

Backbone View Render with Loop no data?

I'm currently building a backbone JS page with underscore and require, everything seems to work but my HTML gets renderd the correct number of times but without the data?

Please check image at bottom of post, it will explain it better.

Files :

js/route.js (Loads home page content fine, catergorieList is what I'm trying to render on home page )

define([
      'jquery',
      'underscore',
      'backbone',
      'views/home/HomeView',
      'views/categories/CategoriesView',
    ], function($, _, Backbone, HomeView, CategoriesView) {
      var AppRouter = Backbone.Router.extend({
        routes: {
          '*actions': 'defaultAction'
        }
      });
      var initialize = function(){

        var app_router = new AppRouter;
        app_router.on('route:defaultAction', function (actions) 
        {
            var categoriesList = new CategoriesView();
            categoriesList.render();

            var homeView = new HomeView();
            homeView.render();
        });

        Backbone.history.start();
      };
      return {
        initialize: initialize
      };
});

js/views/categories/CategoriesView.js

define([
      'jquery',
      'underscore',
      'backbone',
      'models/CatergoriesModel',
      'collections/CategoriesCollection',
      'text!templates/categories/categoriestemplate.html'
    ], function($, _, Backbone, catModel, catCollection, catTemplate){

      var Categories = Backbone.View.extend({
        initialize:function() {
            _.bindAll(this, 'render');
            this.collection = new catCollection([]);
            this.collection.bind('reset', this.render)
            this.collection.fetch();
            this.render();
        },

        render: function(){
          var data = {
            categories: this.collection.models
          };
          var compiledTemplate = _.template( catTemplate, data );
          $("#categoriesList").append(compiledTemplate);
        }

      });

      return Categories;
    });

js/collections/CategoriesCollection.js

define([
    'underscore',
    'backbone',
    'models/CatergoriesModel'
], function(_, Backbone, CatergoriesModel) {

    var CatergoriesCollection = Backbone.Collection.extend({

        model: CatergoriesModel,

        initialize: function() {
            this.fetch({
                success: this.fetchSuccess,
                error: this.fetchError
            });
        },

        url: function() {
            return 'api/categories.json';
        },

        fetchSuccess: function(collection, response) {
            return response._embedded.categories;
        },

        fetchError: function(collection, response) {
            throw new Error("Books fetch error");
        }

    });
    return CatergoriesCollection;
});

js/models/CatergoriesModel.js

define([
    'underscore',
    'backbone',
], function(_, Backbone) {
    var CatergoriesModel = Backbone.Model.extend({});
    return CatergoriesModel;
});

templates/categories/categoriestemplate.html

<% _.each(categories, function(category) { %> 
    <li data-catid="<%= category.id %>">
        <a href="#category/<%= category.id %>">
            <span class="fa fa-angle-double-right text-primary"></span><%= category.name %>
        </a>
    </li>
<% }); %>

enter image description here API Data

     "_embedded":{
          "categories":[
             {
                "id":1342,
                "name":"Engineers",

             {
                "id":1344,
                "name":"Squash Courts",

             }...

Upvotes: 1

Views: 467

Answers (1)

Jack
Jack

Reputation: 10993

There are a couple of mistakes that your making. First your trying to parses your json in the fetch success callback, you should instead be overriding your collections parse method for that.

For example :

  parse: function (response) {
      return response._embedded.categories;
    }

The second issue is one of timing, you are calling render on your collection view right after instantiating it, but at that point your fetch call might not have completed yet. Instead you can call your view's render method in the fetch callback.

For example

   initialize:function() {
            _.bindAll(this, 'render');
            var self = this;
            this.collection = new CatergoriesCollection();
            this.collection.fetch({
              success: function () {
                 self.render();
              }
             });
     },

Finally you aren't creating your data object right or passing it to your template correctly.

To get the data from your models you can use the collections toJSON method

  var data = {
        categories: this.collection.toJSON()
      };

And then pass it in to the compiled template (as of underscore 1.7.0 you can no longer pass in the data while compiling the template).

$("#categoriesList").append(compiledTemplate(data));

And here's a link to a jsbin

Upvotes: 1

Related Questions