1

I'm getting an error 'cannot call method 'Deferred' of undefined in the file. error in backbone.marionette.min.js:20

Why? Thanks

config:

require.config({

  baseUrl:"/static/js/portalApp/",

  paths: {
    jquery: '//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min',
    underscore: '//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min',
    backbone: '//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.0/backbone-min',
    marionette: '//cdnjs.cloudflare.com/ajax/libs/backbone.marionette/1.1.0-bundled/backbone.marionette.min',
    bootstrap: '//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.2/js/bootstrap.min',
    templates: '/static/portalApp',

    // Plugins
    handlebars: '//cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.1.2/handlebars.min',
    text: '/static/js/libs/text'






  },

    shim : {
    jquery : {
      exports : 'jQuery'
    },
    underscore : {
      exports : '_'
    },
    backbone : {
      deps : ['jquery', 'underscore'],
      exports : 'Backbone'
    },
    marionette : {
      deps : ['jquery', 'underscore', 'backbone'],
      exports : 'Marionette'
    },
    bootstrap: {
        deps: ['jquery']
    },

    handlebars:{
            "exports": "Handlebars"
    }




   }


});

require(["App", "routers/AppRouter", "controllers/Controller",  "jquery" , "bootstrap"],
    function (App, AppRouter, Controller) {
        App.appRouter = new AppRouter({
            controller:new Controller()
        });
        App.start();
    });

App.js

define(['jquery', 'backbone', 'marionette', 'underscore'],
    function ($, Backbone, Marionette, _) {
        var App = new Backbone.Marionette.Application();


        //Organize Application into regions corresponding to DOM elements
        //Regions can contain views, Layouts, or subregions nested as necessary
        App.addRegions({
            headerRegion:"header",
            mainRegion:"#main"
        });

        App.addInitializer(function () {
            Backbone.history.start();
        });


        return App;
    });

Router

define(['backbone', 'marionette'], function(Backbone, Marionette) {
   return Backbone.Marionette.AppRouter.extend({
       //"index" must be a method in AppRouter's controller
       appRoutes: {
           "": "index"
       }
   });
});

Controller:

define(['App', 'backbone', 'marionette', 'views/HeaderView'],
    function (App, Backbone, Marionette, HeaderView) {

     return Backbone.Marionette.Controller.extend({
        initialize:function (options) {
            App.headerRegion.show(new HeaderView());
        },
        //gets mapped to in AppRouter's appRoutes
        index:function () {
            //App.mainRegion.show(new WelcomeView());
        }
    });
});
Prometheus
  • 32,405
  • 54
  • 166
  • 302
  • I'm pretty sure my diagnosis in my answer below is correct but I can't reproduce the error you get. Are you sure there is not something *outside* RequireJS which loads Backbone prematurely? Maybe something like a `` – Louis Nov 13 '13 at 12:48

1 Answers1

3

The error you get is consistent with Backbone not finding jQuery. The Marionette source code contains exactly two instances of the symbol Deferred. Both times, it is:

this._deferred = Marionette.$.Deferred();

And Marionette.$ is initialized like this:

Marionette.$ = Backbone.$;

and we've already established that Backbone.$ is set to jQuery's $ symbol.

So if Backbone cannot find jQuery, then Backbone.$ is undefined and Marionette.$ is undefined and this undefined value cannot have a Deferred method. Hence, "cannot call method 'Deferred' of undefined[...]"

Community
  • 1
  • 1
Louis
  • 146,715
  • 28
  • 274
  • 320
  • Right, whats confusing me it that I'm taking this directly from the example here https://github.com/BoilerplateMVC/Marionette-Require-Boilerplate-Lite/blob/master/public/js/app/config/Init.js why do they not have the same issue. – Prometheus Nov 13 '13 at 12:07
  • 1
    Also I keep reading that jQuery is auto set by require.js so there should not be any need to do this, right? Is my setup doing something fundamentally wrong? – Prometheus Nov 13 '13 at 12:09
  • Maybe those guys at BoilerplateMVC are using a different version of Backbone. jQuery does not need shimming to be used with RequireJS but that does not mean that Backbone can find it. – Louis Nov 13 '13 at 12:17
  • The inti method worked before I starting using Marionette if I add it back in I now get: Object function (n){return n instanceof j?n:this instanceof j?(this._wrapped=n,void 0):new j(n)} has no method 'Deferred' - same line as before. – Prometheus Nov 13 '13 at 12:19
  • I have just tested by added their local libs and it gave the same message. I would love to get the bottom of this. The hack above with the init method does not seem to work this time with Marionette either, sorry. – Prometheus Nov 13 '13 at 12:25
  • Right so what I can tell is that it seems that jquery path does not load in the right order, not matter what I do – Prometheus Nov 13 '13 at 12:47