"Route Not Found" in console window when Durandal is trying to load first page of app - durandal

I'm getting "Route not found" in the console window on trying to load an app converted from 1.2 to 2.0. Is there any way I can debug what route it's trying to find at the point of failure please? It would be handy if it said, "cannot find route:/viewmodels/wrongfolder/startup" or something!
Please be aware that ALL of this was working perfectly prior to upgrading from 1.2 to 2.0, so it's differences in the Durandal settings that I need to address. No files have been removed or lost or moved, so it's not that things have changed in the app outside of the new versions of scripts being updated by nuget.
main.js and config.js live in root of "app" folder. Shell.js is in app/viewmodels and shell.html is in app/views. All views/viewmodels are in the relevant folders below the main /app folder.
I have a "config.js" file with routes returned:
var routes = [{
route: 'home',
moduleId: 'home',
title: 'Home',
nav: true
}, {
route: 'labTool',
moduleId: 'labTool',
title: 'Lab Tool',
nav: true
}];
var startModule = 'labTool';
main.js:
//specify which plugins to install and their configuration
app.configurePlugins({
router: true,
dialog: true,
widget: false
});
app.start().then(function () {
viewLocator.useConvention();
router.makeRelative({ moduleId: 'viewmodels' });
app.setRoot('viewmodels/shell');
router.handleInvalidRoute = function (route, params) {
logger.logError('No route found', route, 'main', true);
};
});
Shell.js:
var inEditMode = ko.observable(false); //set edit mode to false at start
var shell = {
activate: activate,
router: router,
inEditMode: inEditMode
};
return shell;
function activate() {
return datacontext.primeData()
.then(boot)
.fail(failedInitialization);
}
function boot() {
logger.log('Application Loaded!', null, system.getModuleId(shell), true);
router.map(config.routes).buildNavigationModel();
return router.activate(config.startModule);
}
function failedInitialization(error) {
var msg = 'App initialization failed: ' + error.message;
logger.logError(msg, error, system.getModuleId(shell), true);
}
Some of the code may still need editing to handle the change from 1.2 to 2.0 but I think I have most of it now.

I had a similar problem after the upgrade and creating a default route with a route property of '' sorted it for me.
So instead of using your startModule property try setting you labTool route to have a route property of ''.

In case anyone else runs into this, this error can also occur if you have non-ascii characters in the route name.
Not working:
{ route: 'Møøse', ... }
Working:
{ route: 'Moose', title: 'Møøse', ... }

Related

Aurelia child router does not go through main router pipeline

The main router's pipeline of my application redirects to login page if a user is not logged in.
It works fine for most pages, but when said page holds itself a child router, the logic does not seem to hit the main router's pipeline, preventing redirection (as well as not rendering the page).
main router:
configureRouter (rc: RouterConfiguration, router: Router) {
this.router = router;
rc.addAuthorizeStep(this.requireAuth);
const auth = { authenticated: true, needsCurrentOrg: true };
const loginRoute = {
route: 'login/:token?',
name: 'login',
moduleId: PLATFORM.moduleName('views/login/login'),
};
rc.map([
{
route: [ROOT_PAGE, DASHBOARD_PAGE],
name: DASHBOARD_PAGE,
moduleId: PLATFORM.moduleName('views/dashboard/dashboard'),
settings: auth
},
{
route: CREDENTIALS_PAGE,
name: CREDENTIALS_PAGE,
moduleId: PLATFORM.moduleName('views/credentials/credentials-root'),
settings: auth
})]
}
credentials router:
configureRouter (rc: RouterConfiguration) {
rc.map([
{
route: '',
name: 'credentials-list',
moduleId: PLATFORM.moduleName('./credentials-grid'),
}
]);
}
So if I hit /#/dashboard without being logged in, I get redirected to /login, but nothing happens if I hit /#/credentials: blank page, no redirection. I put a debugger in the requireAuth middle-ware code, and in the first case it does step in, in the second case it does not go through
Finally identified the issue, for some reasons it looks like the LoadRouteStep pipeline step (internal to the AppRouter) tried to load the ViewModel of the subrouter target.
Since this ViewModel had some code in the constructor, that code was failing, creating an error and stopping the pipeline - never reaching the redirection.
The fix was to move that constructor code into an activate function for the ViewModel.

ui.router netsted state which defined in another module not work when refresh page

My app has two angular modules (hub and bApp). hub module is a container for another modules (bApp). I use ui.router for routing and config as follow as:
In hub.js (hub module) file:
var hub = angular.module('hub', ['ui.router', 'bApp']).config(function ($stateProvider) {
$stateProvider.state({
name: 'hub',
url: '/',
templateUrl: 'hub/views/main.html',
controller: 'MainCtrl'
}).state({
name: 'hub.frontends',
url: 'frontend',
templateUrl: 'hub/views/frontend.html',
controller: 'FrontendCtrl',
resolve: {
frontendList: function (getList) {
return getList.getAll('/api/frontend');
}
}
})
$locationProvider.html5Mode({ enabled: true, requireBase: true }).hashPrefix('!');
});
In bApp.js (bApp module) file:
var bApp = angular.module('bApp',[]).config(function($stateProvider){
$stateProvider.state({
name: 'hub.book',
url: 'book',
templateUrl: 'book/views/book.html',
controller: 'bookCtrl',
resolve: {
bookList: function(getList){
return getList.getAll('/api/book');
}
}
}).state({
name:'hub.book.test',
ulr:'book/test',
template: '<h1>test</h1'
});
});
Finally in express server, I config as follow as (just for working with html5Mode):
app.all('/user/*', function (req, res, next) {
res.sendFile('static/user/index.html', { root: __dirname });
});
Everything works well if I only navigate between states by $state.go. But when I refresh or enter url to browser and press enter, only states which defined in hub module is work.
States which defined in bApp module is not work. But hub.run() still work normally, but just show a blank page with no error.
I don't know how to figure out this problem.
Thanks!

Multiple start pages in Durandal

I have included my main.js and shell.js below for reference. As you can see my default route in the shell.js is the viewmodels/search and it has a second route to viewmodels/application with can take an option parameter, which is the IDKey for a particular application. Most of the time this is how I want users to enter the system by starting with the search screen where they can search for a particular application or have the option to click a button to start a new application. However I would like to be able to publish url links that could skip the search page and start the application with the viewmodels/application page with the appropriate IDKey.
I just cannot seem to figure out how to implement this behaviour. Can anybody get me pointed in the right direction of how to implement this.
MAIN.JS
define('jquery', [], function () { return jQuery; });
define('knockout', [], function () { return ko; });
define(['durandal/system', 'durandal/app', 'durandal/viewLocator'], function (system, app, viewLocator) {
app.title = 'My App';
//specify which plugins to install and their configuration
app.configurePlugins({
router: true,
dialog: true,
widget: {
kinds: ['expander']
}
});
app.start().then(function () {
toastr.options.positionClass = 'toast-bottom-right';
toastr.options.backgroundpositionClass = 'toast-bottom-right';
viewLocator.useConvention();
app.setRoot('viewmodels/shell', 'entrance');
});
});
SHELL.JS
define(['plugins/router'], function (router) {
return {
router: router,
activate: function () {
return router.map([
{ route: '', moduleId: 'viewmodels/search', title: 'Permit Application Search', nav: true },
{ route: 'application(/:id)', moduleId: 'viewmodels/application', title: 'Permit Application', nav: true }
]).buildNavigationModel()
.activate();
}
};
});
Following your routes as shown in code, you should simply be able to publish a link like http://yourdomain.com#application/12

HandleInvalidRoute not working with Durandal

Here's my shell.js vm:
var vm = {
router: router,
auth: auth,
viewAttached: function () {
},
activate: function () {
router.useConvention();
router.handleInvalidRoute = function (route, params) {
debugger;
toastr.info('No Route Found: ' + route);
};
router.map([
{ url: 'error', moduleId: 'viewmodels/error', name: 'Error', visible: false }
]);
router.mapAuto();
if (auth.isAuthenticated)
//return router.activate('folder/2');
return router.activate('home');
else {
return router.activate('home');
}
}
};
return vm;
});
When I navigate to an invalid route (/folders, for example), the debugger in my handleInvalidRoute block isn't hit, and I get a scripterror from require.js:
GET http://appname.com/App/viewmodels/folders.js 404 (Not Found)
require.js:33 Uncaught Error: Script error
http://requirejs.org/docs/errors.html#scripterror require.js:8 J
require.js:8 j.onScriptError
That's all I have to work with. Any idea what's going on?
This has been answered by #EisenbergEffect in the Durandal newsgroup https://groups.google.com/forum/#!topic/durandaljs/eZrIcgn3aU8.
It is because you called mapAuto which always attempts to map urls to
modules, whether or not they actually exist. Effectively,
handleInvalidRoute will never be called.

router.guardRoute is not being called

This is probably a simple one..
I am trying to override the routers guardRoute function and it seems that my version is not being called.
Code
app.start().then(function () {
router.useConvention();
viewLocator.useConvention();
app.setRoot('viewmodels/shell', 'entrance');
router.handleInvalidRoute = function (route, params) {
logger.logError('No route found', route, 'main', true);
};
router.guardRoute = function (routeInfo, params, instance) {
logger.logError('guardRoute called', routeInfo, 'main', true);
return false;
};
});
Edit 1 - Entire main.js file shown
require.config({
paths: { "text": "durandal/amd/text" }
});
define(function (require) {
var system = require('durandal/system'),
app = require('durandal/app'),
router = require('durandal/plugins/router'),
viewLocator = require('durandal/viewLocator'),
logger = require('services/logger');
system.debug(true);
app.title = "my app";
app.start().then(function () {
router.useConvention();
viewLocator.useConvention();
app.setRoot('viewmodels/shell', 'entrance');
router.handleInvalidRoute = function (route, params) {
logger.logError('No route found', route, 'main', true);
};
router.guardRoute = function (routeInfo, params, instance) {
logger.logError('guardRoute called', routeInfo, 'main', true);
//return false;
};
});
});
I do not get my log message and the router continues to process the request. What am I doing wrong?
I have just checked the release form of Durandal 1.2.0 https://github.com/BlueSpire/Durandal/blob/master/Changes.txt
And yes the guardRoute is added from this version.
You can check which versions you have in the packages.config file!
The hottowel template you own is probably version 1.1.1 of DurandalJS, this I can see in the NuGet Package Manager. If I want to download the HotTowel template right now it contains DurandalJS 1.1.1
You should update Durandal in the NuGet Manager and also the Durandal Router, then everything should work fine!
I have done this update to (but not from hottowel) and I clicked update ALL, DON'T click this, this will also update/ download Durandal Starterskit and your back at '0'.