Search code examples
javascriptphprestbackbone.js

Backbone view/template fails to load from REST


I have properly coded a simple REST api and several backbone models. My parent model is called Topic and child model called Questions.

I'm trying to call a get method on the REST api and display the received Topic object to the user in a presentable manner. I am receiving the json (can be seen in the network tab on Chrome), but it is not getting sent to the view correctly.

Model:

var Topic = Backbone.Model.extend({
    urlRoot: ROOT + '/topic',
    idAttribute: 'topicId',
    initialize: function () {
        this.questions = new Questions([], {parent: this});
    },
    toJSON: function () {
        var json = Backbone.Model.prototype.toJSON.call(this);
        json.questions = this.questions.toJSON();
        return json;
    }
});
var Topics = Backbone.Collection.extend({
    model: Topic,
    url: ROOT + 'topic',
    parse: function (response) {
        return response.results;
    }
})

REST URL:

http://localhost/Project/index.php/rest/resource/topic/

Backbone View: This is where I think the error is...(console log below prints an empty object)

var TopicListView = Backbone.View.extend({
      el: '.page',
      render: function () {
        var that = this;
        var topics = new Topics();
        topics.fetch({
          success: function (topics) {
              console.log(topics);
            var template = _.template($('#topic-list-template').html(), {topics: topics.models});
            that.$el.html(template);
          }
        })
      }
    });

Using the above functions:

var topic = new Topic();
topic.fetch();
topicListView = new TopicListView();

var Router = Backbone.Router.extend({
    routes: {
        "": "home"
    }
});
var router = new Router;

// render topic list for 'home'
router.on('route:home', function () {
    topicListView.render();
});

Edit: Solution: Overriding the parse function in the collection proved to be the error. I wonder why...


Solution

  • The argument topics in your success handler is shadowing the variable topics.

    The argument contains the parsed JSON response, not the Backbone Collection. You don't need that, so you can remove the argument.

    The reference to topics will now be to your Collection, so topics.models will have the value you expect.

    topics.fetch({
      success: function () { // argument removed here so `topics` is no longer shadowed
        var template = _.template($('#topic-list-template').html(), { topics: topics.models });
        that.$el.html(template);
      }
    })