The otherwise()
part handles paths that do not match any specified routes.
In this scenario, the route matches but the template is not available at the given URL.
$routeProvider
is unaware of this situation and can't take significant action.
To address this issue, you can somehow (details below) check if the template exists, and if it doesn't, use $location
to redirect to an appropriate path (e.g. /error/404
).
One method to determine page validity (i.e., template availability) is to try accessing the template (using $http
) and handle any errors indicating template absence. However, relying solely on template existence for assessing a page's validity may result in misleading error messages during network or server issues, among other drawbacks.
A preferable approach could involve maintaining a list of "valid" pages and cross-referencing against it. If the current page should exist, proceed with fetching the template as usual. Otherwise, direct to an error page.
This logic can be implemented within the $routeProvider
's resolve
property to execute before controller instantiation and view loading.
For example:
var app = angular.module(...);
// Make this a constant so it can be injected into configuration blocks
app.constant('EXISTING_PAGES', [
'page1',
'page2',
...
]);
app.config(function configRouteProvider($routeProvider, EXISTING_PAGES) {
$routeProvider.
when('/', {
templateUrl: 'views/dashboard.html'
}).
when('/:page', {
templateUrl: function getPageTemplateUrl(routeParams) {
return 'views/' + routeParams.page + '.html';
},
resolve: {
exists: function resolveExists($location, $route) {
// Access parameters via `$route.current.params` since this runs before controller instantiation
if (EXISTING_PAGES.indexOf($route.current.params.page) === -1) {
// Redirect to suitable error page if the page is invalid/non-existent
$location.replace();
$location.path('/error/404');
}
return true;
}
}
}).
// Define a separate route to redirect to
when('/error/404', {
templateUrl: '404.html'
}).
otherwise({
redirectTo: '/error/404'
});
});
Check out this brief demo as well.