I've the following routing:
//Root routes
const routes: Routes = [
{
path: '',
component: AuthenticatedLayoutComponent, //All childs pages will have headers
children: [
{ path: '', redirectTo: 'documents', pathMatch: 'full' },
{ path: 'documents', loadChildren: () => import('./documents/documents.module').then(m => m.DocumentsModule) },
{ path: 'settings', loadChildren: () => import('./settings/settings.module').then(m => m.SettingsModule) },
{ path: 'accounts', loadChildren: () => import('./account/account.module').then(m => m.AccountModule) },
],
canActivate: [AuthGuard],
},
{
//The goal of separating auth and account is to have the pages to becomes authentified in the Auth module, with a totally different layout
path: 'auth',
loadChildren: () => import('./auth/auth.module').then(m => m.AuthModule),
canActivate: [UnauthGuard],
},
];
and then, for the child "AccountModule", I've the following routes:
const routes: Routes = [
{ path: 'profile', component: ProfileComponent },
{ path: '', redirectTo: 'profile', pathMatch: 'full' },
];
My AuthenticatedLayoutComponent
has basically just a header/footer and a router-outlet:
<div id="container" >
<header >
<app-header></app-header>
</header>
<main >
<router-outlet></router-outlet>
</main>
<footer >
<app-footer></app-footer>
</footer>
</div>
- If I try to access to
http://localhost:4200/accounts/profile
everything works - But a strange thing is that if I'm trying to access to
http://localhost:4200/profile
I'm also redirected to my ProfileComponent, without my header/footer.
Why is this considered a valid path and how do I prevent it?
CodePudding user response:
Like figured out in the comments, the problem is that the application root module imports AccountModule
because it contains something that the application root module needs. In that moment, the route definition of the AccountModule
is loaded, which exposes the /profile
route.
One way to fix it, is to resolve the dependency between the root module and the AccountModule
, and stop importing it. Then the module with its route definition is only loaded via lazy loading, making the /profile
route unavailable. But possibly this will be a lot of effort.
Another quicker way to fix it, is to remove lazy loading from the /accounts
route and define its sub-routes directly in your root routing module:
//Root routes
const routes: Routes = [
{
path: '',
component: AuthenticatedLayoutComponent, //All childs pages will have headers
children: [
// ...
{
path: 'accounts',
children: [
{ path: 'profile', component: ProfileComponent },
{ path: '', redirectTo: 'profile', pathMatch: 'full' },
]
},
],
canActivate: [AuthGuard],
},
// ...
];
CodePudding user response:
Strongly inspired by @JSONDerulo answer:
Since I cannot use lazy loading but I still would like to have my rules enclosed in my accounts module:
- I now declare the module in my AppModule
- I export my account routes and use them as childs in my AppRoutingModule
- I removed the import of the AccountRoutingModule of my AccountModule
AppRoutingModule:
import { routes as accountsRoutes } from './account/account-routing.module';
const routes: Routes = [
{
path: '',
component: AuthenticatedLayoutComponent, //All childs pages will have headers
children: [
{ path: '', redirectTo: 'documents', pathMatch: 'full' },
{ path: 'documents', loadChildren: () => import('./documents/documents.module').then(m => m.DocumentsModule) },
{ path: 'settings', loadChildren: () => import('./settings/settings.module').then(m => m.SettingsModule) },
{ path: 'accounts', children: accountsRoutes },
],
canActivate: [AuthGuard],
},
{
//The goal of separating auth and account is to have the pages to becomes authentified in the Auth module, with a totally different layout
path: 'auth',
loadChildren: () => import('./auth/auth.module').then(m => m.AuthModule),
canActivate: [UnauthGuard],
},
];
AccountRoutingModule
export const routes: Routes = [
{ path: 'profile', component: ProfileComponent },
{ path: '', redirectTo: 'profile', pathMatch: 'full' },
];