2
votes

It's my first attempt using Marionette. I'm trying to instantiate a Marionette Application as a requirejs module. I have been following the Using Marionette with Require js article on the Marionette.js wiki:-

https://github.com/marionettejs/backbone.marionette/wiki/Using-marionette-with-requirejs

I think I have all my shims, dependencies and files in order as I am able to instantiate Views, Models etc in the same place without error but I can't figure out the issue with my Application. Any help or guidance would be much appreciated!

Here is my index.html:-

<!DOCTYPE html>
<html>
<head>
    <title>Marionette Structure and Require AMD Proto</title>
    <link rel="stylesheet" type="text/css" href="css/styles.css">
</head>
<body>
<div id="nav">

</div>
<div id="mainContent">

</div>
<script language="javascript">
    // convenience function, because console.log throws errors and crashes IE
    // this way you don't need to all logs to test in IE
    function trace(msg){
        try{
            console.log(msg);
        }catch(e){
            // suppressed error
        }
    }
</script>
<script src="js/lib/require.js" data-main="app.js"></script>
</body>
</html>

Here is my app.js:-

require.config({
    paths : {
        backbone : 'js/lib/backbone',
        underscore : 'js/lib/underscore',
        jquery : 'js/lib/jquery',
        marionette : 'js/lib/backbone.marionette'
    },
    shim : {
        jquery : {
            exports : 'jQuery'
        },
        underscore : {
            exports : '_'
        },
        backbone : {
            deps : ['jquery', 'underscore'],
            exports : 'Backbone'
        },
        marionette : {
            deps : ['jquery', 'underscore', 'backbone'],
            exports : 'Marionette'
        }
    }
})

require(
    ["jquery",
        "underscore",
        "backbone",
        "marionette",
        "js/shell/shellapp"
    ],
    function($, _, Backbone, Marionette, ShellApp) {
        $(function() {
           new ShellApp();
            trace("ShellApp: "+ShellApp);
        });
    }
);

And finally here is my shellapp.js:-

define( ["marionette"], function (Marionette) {

    // set up the app instance
    var ShellApp = new Marionette.Application();

    // configuration, setting up regions, etc ...
    ShellApp.addRegions({
        nav: '#nav',
        main: '#mainContent'
    });
    ShellApp.on('initialize:after', function(){
        trace("initialize:after");
    });
    // export the app from this module
    return ShellApp;
});

Put it all together and I get "Uncaught TypeError: object is not a function " at app.js line 42

Much thanks to anyone who got this far!

Sam

1
I don't know Marionette, but it looks like you're exporting an Object (return ShellApp;) then trying to new it up, like a constructor function, when you import it (new ShellApp();).c24w
Thanks c24w, that is what I was trying to do (although perhaps I don't need to...). I was following the tutorial and that's where I thought I could or had to instantiate a new ShellApp() once I imported it. It seems I don't have to.... but why is it like that in the tutorial?SamBrick

1 Answers

3
votes

My answer got too long for a comment!

You're exporting a constructed Object, rather than the constructor itself:

var ShellApp = new Marionette.Application()
...
return ShellApp;

which is exactly what gets imported, hence you don't need to create another new one.

Firstly, I would rename ShellApp to shellApp to denote an instance, rather than a constructor (which is a common naming convention). I think it's quite misleading in the tutorial that they break this convention:

MyApp = new Backbone.Marionette.Application();

(assuming I'm on the right lines here).

I now assume that you just pass this single instance of Marionette.Application around, for the lifetime of your app.

In the tutorial, it shows the exporting of a newed-up Marionette.Application (the same as you have done), but doesn't show it actually being used when imported. After importing the object, you can access it's properties, such as:

shellApp.addInitializer(function(options){
    // stuff
});

More here.