Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular routing with multiple modules and dynamic routes

I've an Angular (4) app with the following structure:

app.module
   bi.module
   auth.module

The routing should be:

/ -> redirect to /home
/home -> use HomeComponent
/auth -> redirect to /auth/login
/auth/login -> use LoginComponent
/auth/register -> use RegisterComponent
any other thing -> use PageComponent

The thing is that this routing is splitted into different modules and I'm also using lazy loading so that the bi.module is only loaded when needed (after user is logged in, basically). Now, my auths routes are working and if I type /home this is also working, but the empty / or any other ones are not working.

This is my app.module.ts

const routes: Routes = [
  {
    path: '',
    pathMatch: 'full',
    redirectTo: 'home'
  },
  {
    path: 'home',
    component: HomeComponent,
    canActivate: [AuthGuard]
  },
  {
    path: '**',
    loadChildren: './bi/bi.module#BiModule'
  }
];

...

imports: [
    ...
    AuthModule,
    RouterModule.forRoot(routes, { enableTracing: true }),
    BiModule
  ],

My auth.module is working fine, so no need for it. My bi.module

const routes: Routes = [
  {
    path: '',
    component: PageComponent,
    canActivate: [AuthGuard],
    resolve: {
      content: PageResolve
    }
  }
];

...

imports: [
    ...
    RouterModule.forChild(routes)
  ],

When I go '/', my wildcard route in biModule is activated and my PageComponent is rendered instead of redirecting to /home.

This is my trace from the router:

Router Event: NavigationStart
NavigationStart(id: 1, url: '/')
NavigationStart {id: 1, url: "/"}
Router Event: RoutesRecognized
RoutesRecognized(id: 1, url: '/', urlAfterRedirects: '/', state: Route(url:'', path:'') { Route(url:'', path:'**') } )
RoutesRecognized {id: 1, url: "/", urlAfterRedirects: "/", state: RouterStateSnapshot}
Router Event: NavigationEnd
NavigationEnd(id: 1, url: '/', urlAfterRedirects: '/')
NavigationEnd {id: 1, url: "/", urlAfterRedirects: "/"}

PageComponent

The last trace (PageComponent) is a console.log in my component.

Any idea what I'm doing wrong? Thanks

like image 776
David Avatar asked Nov 23 '25 16:11

David


1 Answers

The route that you have defined in the bi.module has a path of "". This will conflict with your home route which also has a path of "".

When you add your routes in the bi.module using RouterModule.forChild(routes) this prepends your new modules routes to the entire routes object. When you naviage to path "", angular finds the first path that matches the criteria, in this case it will be the PageComponent route. This is how the angular router is suppose to behave.

Every path in all routes must be unique, and therefore defining two routes with path "" without a module prefix on the second will cause error.

https://angular.io/guide/router#lazy-loading-route-configuration

It might not be possible to use the lazy loaded route as the wild card directly, but if you defined a wild card route in your app.module which redirected to the route in the bi.module you need, then this may redirect correctly.

I.E in app.module.

{
  path: '/bi',
  loadChildren: './bi/bi.module#BiModule'
},
{
  path: '**',
  redirectTo: '/bi'
}

then in bi.module

{ path: 'bi', 
  children: [ { 
    path: '**', 
    component: PageComponent, 
    canActivate: [AuthGuard]
  }]
}

This does mean all routes in the bi module will be appended with the '/bi', but this is necessary to allow both "" paths to be used.

like image 182
Andrew Stalker Avatar answered Nov 25 '25 11:11

Andrew Stalker