I am facing an issue.
In my multi-module application with lazy loading, I encountered a strange behavior when trying to navigate between child lazy modules. Transition from top module to bottom child module works fine, but routing from one bottom child lazy module to another causes problems.
Here are some scenarios that work:
=> http://localhost:4200/#/op/services/ =>
=> http://localhost:4200/#/op/services/management/ =>
=> http://localhost:4200/#/op/services/management/edit/123
=> http://localhost:4200/#/op
=> http://localhost:4200/#/op/test/management/
=> http://localhost:4200/#/op/test/management/edit/321
And here is the problematic scenario:
http://localhost:4200/#/op/test/management/edit/321 =>
=> http://localhost:4200/#/op/services/management/edit/123
When I attempt this navigation, the URL starts with '?' and the app undergoes a full reload!
Surprisingly, whether or not a lazy module is loaded does not impact the issue at all.
This problem occurs inconsistently, sometimes the transition works just as intended! Despite attempting various combinations, I have been unable to resolve the issue.
Things I have tried include:
this.router.navigate([op/services/management/edit/${id}]);
this.router.navigate([/op/services/management/edit/${id}]);
this.router.navigate(['/op/services/management/edit/', id]);
this.router.navigateByUrl(op/services/management/edit/${id});
this.router.navigateByUrl(/op/services/management/edit/${id});
routerLink = "/op/services/management/edit/123"
routerLink = "op/services/management/edit/123"
I need help understanding why the route changes unexpectedly.
UPDATE.
Added simplified route configuration:
Base module:
const routes: Routes = [
{
path: '', loadChildren: './path/to/op.module#OperatorModule',
data: {
preload: false,
base: true,
},
},
...
];
@NgModule({
imports: [RouterModule.forRoot(
routes,
{
useHash: true,
preloadingStrategy: SelectivePreloadingStrategy,
},
)],
exports: [RouterModule],
})
export class AppRoutingModule {}
Operator module containing inner lazy modules:
const routes: Routes = [
{
path: 'op',
component: BasePage,
canActivate: [AuthGuard],
children: [
{
path: 'services/management',
loadChildren: './services/services.module#ServicesModule',
canActivate: [AuthGuard],
data: {
preload: true,
},
},
{
path: 'tests/management',
loadChildren: './tests/tests.module#TestsModule',
canActivate: [AuthGuard],
data: {
preload: true,
},
},
...
],
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class OperatorRoutingModule {
}
Router modules for some of the inner modules:
For services:
const routes: Routes = [
{
path: '',
data: {
...
},
pathMatch: 'full',
component: ServicesPage,
canActivate: [AuthGuard],
},
{
path: 'edit/:id',
data: {
accessRole: [UserRole.USER, UserRole.ADMIN],
},
component: ServicePage,
canDeactivate: [CanDeactivateGuard],
canActivate: [AuthGuard, RoleGuard],
},
....
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class ServicesRoutingModule {
}
For tests:
const routes: Routes = [
{
path: '',
data: {
...
},
pathMatch: 'full',
component: TestsPage,
canActivate: [AuthGuard],
},
{
path: 'edit/:id',
data: {
accessRole: [UserRole.USER, UserRole.ADMIN],
},
component: TestPage,
canDeactivate: [CanDeactivateGuard],
canActivate: [AuthGuard, RoleGuard],
},
....
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class TestsRoutingModule {
}
UPDATE!
I recently discovered a new reason for the problem.
The issue arises when attempting to route using an HTML form. I have a CanDeactivate service warning about leaving the page, and even with this service disabled on the page, the window:beforeunload
event still triggers on any form submission.
Although it's unclear how these elements are interconnected, I feel like I'm making progress towards solving the issue.