Search code examples
javascriptbackbone.jsrequirejsjs-amd

listenTo on collection reset doesn't get invoked after collection is fetched


Below is my initialization function of a view that should receive a module name when initialized in order to fetch the correct data from the collection.

The issue is:

  1. Listento doesn't redirect to the render() method after the collection is fetched, also it gives me an error on the console

TypeError: e is undefined

What is the mistake i made with the code below??

    initialize: function() {          

     var that = this;
        if(this.options.module === 'questions'){                  

            require([
                'app/collections/questions'
            ], function(QuestionsCollection){                   
                var moduleCollection = new QuestionsCollection();
                that.collection = moduleCollection;
                moduleCollection.fetch({
                    reset: true, 
                    success: function(){},
                    error: function(){}
                    });                                                                        
            });                

        }

        this.listenTo(this.collection, 'reset', this.render);
        this.listenTo(Backbone, 'close:Home', this.close);
    },

Solution

  • You problem is riquire.js, when you write require([/*jsFile*/], callback); the call to callback is made asynchronously after the jsFile is loaded. So when you call require([... immediatly after that you call this.listenTo(this.collection, 'reset', this.render); and at the time this last line is executed the jsFile is not yet loaded and the callback is not yet called thus the this.collection is undefined.

    Take a look at this example http://jsfiddle.net/ZZuGC/1/ and the order the console.log('require'); & console.log('listenTo'); are printed to the console.


    I think that the solution to your problem is as follows :

    initialize: function() {          
    
     var that = this;
        if(this.options.module === 'questions'){                  
    
            require([
                'app/collections/questions'
            ], function(QuestionsCollection){                   
                var moduleCollection = new QuestionsCollection();
    
                that.collection = moduleCollection;
                // here is my suggestion
                that.listenTo(that.collection, 'reset', that.render);
    
                moduleCollection.fetch({
                    reset: true, 
                    success: function(){},
                    error: function(){}
                    });                                                                        
            });                
    
        }
        this.listenTo(Backbone, 'close:Home', this.close);
    },
    

    I have updated the example http://jsfiddle.net/ZZuGC/2/