Search code examples
angularroutesauth-guardrouteparams

Angular avoid Route parameter (:id) and navigate to specific link


In our project, I have to implement a navigation or redirect to a maintenance page, if maintenance mode is activated. I wanted to do this in the AuthGuard service, and do something like:

canActivate(...) {
    if (this.inMaintenance()) {        
    this._navController.navigateForward('settings-maintenance', { replaceUrl: true });
    return false;
    }
}

unfortunately, the project routes settings are like this:

const routes: Routes = [
{
    path: '',
    loadChildren: () => import('./template/template.module').then((module) => 
    module.TemplatePageModule),
    canActivate: [AuthGuard],
},    
{
    path: 'settings-maintenance',
    pathMatch: 'full',
    component: SMaintenanceComponent,
},
{
    path: ':id',
    loadChildren: () => import('./template/template.module').then((module) => 
    module.TemplatePageModule),
    canActivate: [AuthGuard],
},
{
    path: ':id/:params',
    loadChildren: () => import('./template/template.module').then((module) => module.TemplatePageModule),
    canActivate: [AuthGuard],
},
];

so, whenever I try to navigate to settings-maintenance, it will hit the route-guard again because it thinks it is path: ':id'. Is there a way to avoid this? I wanted to avoid to show the login page and directly redirect to the SMaintenance Page without login, but no Idea how to do it.. Otherwise, I will have to check for maintenance mode in the footer or so and then do a redirect there after the login...


Solution

  • Actually, all of your paths will match to the first empty path. You always need to include pathMatch: 'full' with an empty path, or it will match to anything and everything. I suppose nobody has noticed because they all load the same module....

    const routes: Routes = [
    {
        path: '',
        loadChildren: () => import('./template/template.module').then((module) => 
        module.TemplatePageModule),
        canActivate: [AuthGuard],
        pathMatch: 'full',
    },
    ...
    

    It should check for path matches in order, so it will find the maintenance page before the :id page.

    Doc reference: https://angular.io/api/router/Route

    The path-match strategy 'full' matches against the entire URL. It is important to do this when redirecting empty-path routes. Otherwise, because an empty path is a prefix of any URL, the router would apply the redirect even when navigating to the redirect destination, creating an endless loop.

    An empty path without pathMatch: 'full' usually appears as the last route, and is used to catch any routes that don't exist, either redirecting or displaying a 404 page.