Pergunta

I'm working on an application that uses Backbone.js/Marionette. Currently, when I try and fetch my collection from a remote API I get the following error:

Uncaught TypeError: undefined is not a function backbone.js:225
Events.(anonymous function) backbone.js:225
e.CollectionView.e.View.extend._initialEvents backbone.marionette.js:1585
e.CollectionView.e.View.extend.constructor backbone.marionette.js:1548
child backbone.js:1566
List.Controller.listAttractions list_controller.js:9
(anonymous function) app.js:11
triggerEvents backbone.js:207
Backbone.Events.trigger backbone.js:148
e.triggerMethod.d backbone.marionette.js:561
c.extend.start backbone.marionette.js:2461
(anonymous function)

I've tracked the stack trace back, and found that the problem seems to originate in list_controller.js:9. The code for list_controller.js is:

Manager.module("AttractionsApp.List", function(List, Manager, Backbone, Marionette, $, _) {
    List.Controller = {
        listAttractions: function() {
            var attractions = Manager.request("attraction:entities");

            console.log(new Manager.AttractionsApp.List.Attractions());

            var attractionsListView = new Manager.AttractionsApp.List.Attractions({
                collection: attractions
            });

            attractionsListView.on("itemview:attraction:show", function(childView, model) {
                Manager.AttractionsApp.Show.Controller.showAttraction(model);
            });

            Manager.attractionsRegion.show(attractionsListView);
        }
    }
});

It seems that the problem has to do with:

var attractionsListView = new Manager.AttractionsApp.List.Attractions({
    collection: attractions
});

If I comment out the collection: attractions the error goes away. Any idea what is going on here?

Edit Entity file for attractions:

Manager.module("Entities", function(Entities, Manager, Backbone, Marionette, $, _) {
    Entities.Attraction = Backbone.Model.extend({});

    Entities.Attractions = Backbone.Collection.extend({
        url: '/api/attraction/',
        model: Entities.Attraction,
    });

    var attractions;

    var API = {
        getAttractionEntities: function() {
            var attractions = new Entities.Attractions();
            var defer = $.Deferred();
            attractions.fetch({
                success: function(collection, response) {
                    console.log(collection);
                    defer.resolve(collection);
                },
                error: function(collection, response) {
                    console.log("ERROR");
                },
            });

            return defer.promise();
        }
    };

    Manager.reqres.setHandler("attraction:entities", function() {
        return API.getAttractionEntities();
    });
});
Foi útil?

Solução

I think the issue may be API.getAttractionEntities() is returning a promise, not an actual collection which is what Marionette is expecting at line 1585.

Try possibly using attractions.done() (which I renamed to attractionsPromise.done() in the example below) to wrap the creation and management of attractionsListView, like this:

Manager.module("AttractionsApp.List", function(List, Manager, Backbone, Marionette, $, _) {
    List.Controller = {
        listAttractions: function() {
            var attractionsPromise = Manager.request("attraction:entities");

            console.log(new Manager.AttractionsApp.List.Attractions());

            attractionsPromise.done(function(attractions) {
                var attractionsListView = new Manager.AttractionsApp.List.Attractions({
                    collection: attractions
                });

                attractionsListView.on("itemview:attraction:show", function(childView, model) {
                    Manager.AttractionsApp.Show.Controller.showAttraction(model);
                });

                Manager.attractionsRegion.show(attractionsListView);
            });
        }
    }
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top