Search code examples
djangobackbone.jsbackbone-viewsbackbone-routingtastypie

has no method 'toJSON' error in my view


I'm learning backbone.js and I'm building my first multimodule app. I'm getting an error that I've never seen before and I think I know the reason, but I can't see how to fix it. I believe it's because the model isn't actually available to the view yet, but I can't see why.

The error is:

Uncaught TypeError: Object function (){ return parent.apply(this, arguments); } has no method 'toJSON'

This is for line 11 in my view, msg.App.MessageListItemView.

Here's my model:

var msgApp = msgApp || {};

msgApp.Message = Backbone.Model.extend();

Here's my collection:

var msgApp = msgApp || {};

msgApp.MessageCollection = Backbone.Collection.extend({
    model: msgApp.Message,
    url: MESSAGES_API // Call to REST API with Tastypie
});

Here's my list view:

var msgApp = msgApp || {};

msgApp.MessageListView = Backbone.View.extend({

    el: '#gps-app',

    initialize: function() {

        this.collection = new msgApp.MessageCollection();
        this.collection.fetch({reset: true});
        this.render();
        this.listenTo( this.collection, 'reset', this.render );

    },

    // render messages by rendering each message in it's collection
    render: function() {

        this.collection.each(function(item){
            this.renderMessage(item);
        }, this);
    },

    // render a message by creating a MessageView and appending the the element it renders to the messages element
    renderMessage: function(item) {
        var messageView = new msgApp.MessageListItemlView({
            model: msgApp.Message
        });
        this.$el.append(messageView.render().el);
    }

});

Here's my item view:

var msgApp = msgApp || {};

msgApp.MessageListItemlView = Backbone.View.extend({

    tagName: 'li',
    className: 'message-list-item',
    template: _.template($('#messageListItem').html()),

    render: function() {
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    }

});

And here is my router:

var AppRouter = Backbone.Router.extend({

    routes: {
        'messages/': 'allMessages',
    },

    allMessages:function() {
        this.messageList = new msgApp.MessageCollection();
        this.messageListView = new msgApp.MessageListView({model:this.messageList});
        console.log('I got to messages!');
    },

 });

var app_router = new AppRouter;

I'm looking for any and all suggestions. I'm a noob to begin with, and this is my first multimodule app so I'm having a little trouble managing scope I think.

Thanks for you time!


Solution

  • try to change model: msgApp.Message in msgApp.MessageListView like this:

    // render a message by creating a MessageView and appending the the element it renders to the messages element
    renderMessage: function(item) {
        var messageView = new msgApp.MessageListItemlView({
            model: item
        });
        this.$el.append(messageView.render().el);
    }
    

    model parameter in views don't expect type of model, but instance of some model. Hope this helps.