2

I am trying to write a NopCommerce plugin. I have put in my app related files inside plugin's root directory in app named directory. In my shell.js viewmodel I define routes as follows:

define(['durandal/system', 'durandal/plugins/router', 'service/logger','config'],
    function(system, router, logger,config) {

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

        function activate() {
            logger.log('MyProducts Started', null, system.getModuleId(shell), true);
            router.map([
                { route: '', moduleId: 'viewmodels/myProducts', title: 'My Products', nav: true },
                { route: 'searchProducts', moduleId: 'viewmodels/searchProduct', title: 'Search Products', nav: true },
                { route: 'addProducts', moduleId: 'viewmodels/addProduct', title: 'Add Product', nav: true }
            ]).buildNavigationModel();
            return router.activate();
        }

        return shell;
    }
);

Per conventions it should go to first route defined by module: viewmodels/myProducts but I am getting following error:

[viewmodels/shell] MyProducts Started system.js:75
[main] No router found Object
Navigation Complete undefined Object
Uncaught TypeError: Cannot read property 'router' of undefined 

I am banging my head with the well. It is not going to default route (with route:'').

TheVillageIdiot
  • 40,053
  • 20
  • 133
  • 188

3 Answers3

3

Had same problem during route navigation. Turned out to be empty js module file - I made the file but didn't put anything into it yet, and added it to routes.

So, the message can mean that the router got one of the js files you referenced as a source of route controller, but couldn't obtain a page controoler object instance from it.

Ivan Koshelev
  • 3,830
  • 2
  • 30
  • 50
  • Can confirm - this is a weird error that pops up when you try to load a route that points to an empty js file. – BastiBen Nov 17 '15 at 12:52
1

Resolved :)

After much headache, I found out that this is causing the issue:

define([..., 'durandal/plugins/router',...]

When I remove this and it was resolved.

EDIT:- Following is define function inside my main.js file.

define(['durandal/system', 'durandal/app', 'durandal/viewLocator'
                                                            , 'service/logger'],
function (system, app, viewLocator, logger) {
    system.debug(true);

    app.configurePlugins({
        router: true,
        dialog: true,
        widget: true
    });

    app.start().then(function () {
        viewLocator.useConvention();
        app.setRoot('viewmodels/shell', 'entrance');

        //router.mapUnknownRoutes(function (instruction) {
        //    logger.logError('No router found', instruction, 'main', true);
        //});
    });
});
TheVillageIdiot
  • 40,053
  • 20
  • 133
  • 188
  • i'm not sure why that would cause the issue, but the default configuration of durandal creates a path out of 'durandal/plugins' as 'plugins' so it is sufficient to require 'plugins/router'. – Matthew James Davis Sep 30 '13 at 14:15
  • Could you please provide the content for requirejs.config from your main.js. This could be a paths issue. If you had used the HTML samples they are generally set to "../lib/durandal/js/plugins" for Durandal 2.0.0.. – ajeeshpu Nov 25 '13 at 06:16
0

Not to disagree with the convention of the Durandal superstars, but I don't think router information belongs in shell at all. Logically, the router is a part of the core of your application and as such belongs with the application bootstrap logic, in main.js. Here is a typical example of the define call in my main.js:

define(function (require) {

    var system = require('durandal/system'),
        app = require('durandal/app'),
        viewLocator = require('durandal/viewLocator'),
        router = require('plugins/router');

    //>>excludeStart("build", true);
    system.debug(true);
    //>>excludeEnd("build");

    app.title = 'Durandal Starter Kit';
    app.configurePlugins({
        router: true,
        dialog: true
    });

    app.start().then(function() {
        router.map([
            { route: '', title: 'Welcome', moduleId: 'viewmodels/welcome' }
        ]).activate();
        viewLocator.useConvention();
        app.setRoot('viewmodels/shell', 'entrance');
    });
});

I rarely ever use the navigation model feature, so I don't bother to build a navigation model. Other than that, bootstrapping the router is synchronous so it is sufficient to define your routes, activate the router, and then load the shell.

If you do need to use your router in your shell, it is sufficient to add the dependency to your define call as either

define([..., 'plugins/router', ...], function(..., router, ...) { ... });

or

define(function (require) { 
    var router = require('plugins/router');
    ...
});

At which point an already activated router will be exposed to your shell.

Matthew James Davis
  • 12,134
  • 7
  • 61
  • 90
  • Even I am baffled why this happened. even `plugins/router` did not work. I created a sample project from `durandaj getstarted` template and one-by one replaced default files with my own to catch this. – TheVillageIdiot Oct 01 '13 at 00:46
  • Can you confirm: (a) that you have lib/durandal/plugins/router.js in your directory? (b) that you are calling app.configurePlugins({router: true})? – Matthew James Davis Oct 01 '13 at 15:30
  • Yep. I have put the main.js's define function's code in my answer. as you can see I had to comment `mapUnknownRoutes` handler as I'm not passing `router` as required parameters. – TheVillageIdiot Oct 02 '13 at 09:17