Question

The way the navigation template is set up in John Papa's HotTowel SPA template is such that the activate method passed to Durandal in shell.js is a single line (see below). Is this some Javascript pattern that I'm unaware of? What is the reasoning behind not just including the boot code in activate itself?

    var shell = {
        activate: activate,
        router: router
    };

    return shell;

    //#region Internal Methods
    function activate() {
        return boot();
    }

    function boot() {
        log('HotTowel Loaded!', null, true);

        router.on('router:route:not-found', function (fragment) {
            logError('No Route Found', fragment, true);
        });

        var routes = ...
Was it helpful?

Solution

In your code example boot is an anonymous function that isn't evaluated until it is called in the activate method. Durandal calls the activate method after checking for a canActivate method. This is where any initialization code for your view model can go (loading up data, enums, or booting)

The author of the above code probably decided that for the demonstration of how you can use activate it was best to call an anonymous function from there.

Example

For example, let's add some intense console.log'ing to let the user know exactly what is going on

define([], function () {
    var shell = {
        activate: activate,
        router: router
    };

    return shell;

    //#region Internal Methods
    function activate() {
        var user = showUserName();
        initializeVM(user);
        return boot();
    }

    function showUserName() {
        var thisUser = 'You';
        log('User is + thisUser +'!', null, true);
        return thisUser;
    }

    function initializeVM(user) {
        log('Initializing ' + user + '!', null, true);
    }

    function boot() {
        log('HotTowel Loaded!', null, true);

        router.on('router:route:not-found', function (fragment) {
            logError('No Route Found', fragment, true);
        });
    }
});

Obviously we aren't actually doing anything with these functions but understanding what they are to highlight is what we are after. Say we want to go get a user and then initialize the view model with that user and then actually boot up our app to show the first route, this is one way we could do it. By separating the functions (methods) out into their own anonymous function you accomplish a few things -

  1. Separate the concerns - the function only does a small portion of what it needs to instead of having one massive function with all the code in there.
  2. Allows code organization as your application scales - you can easily move these functions into a module which is intended to handle something if it is separated out, especially with Durandal and require.js
  3. You could take it a step further and actually have data calls that return a promise to prevent the application from booting until authentication or something has taken place.

The opposite and uglier code is something like this -

define([], function () {
    var shell = {
        activate: activate,
        router: router
    };

    return shell;

    //#region Internal Methods
    function activate() {
        var thisUser = 'You';
        log('User is + thisUser +'!', null, true);
        log('Initializing ' + user + '!', null, true);
        log('HotTowel Loaded!', null, true);

        router.on('router:route:not-found', function (fragment) {
            logError('No Route Found', fragment, true);
        });
    }
});

Now there isn't a ton of code in the functions above but imagine if each had 10 lines of code - it would get messy quick.

So to answer your question it isn't necessarily a JavaScript specific pattern, it is just a better practice when organizing your code. If you follow some of the PluralSight tutorials that the author put together he often refers to it as modularizing your code (ravoli) vs bunched up code (spaghetti)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top