Suppose the following route configs:
<code>const appRoutes: Routes = [
canMatch: [platformGuard],
canActivate: [authenticationGuard],
resolve: {userConfig: userConfigResolver},
loadChildren: () => import("@netway/home/home.module").then(value => value.HomeModule),
canMatch: [platformGuard],
canActivate: [authenticationGuard],
resolve: {userConfig: userConfigResolver},
loadChildren: () => import("@netway/pwa/pwa.module").then(value => value.PwaModule),
<code>const appRoutes: Routes = [
{
path: "home",
canMatch: [platformGuard],
canActivate: [authenticationGuard],
resolve: {userConfig: userConfigResolver},
loadChildren: () => import("@netway/home/home.module").then(value => value.HomeModule),
},
{
path: "pwa",
canMatch: [platformGuard],
canActivate: [authenticationGuard],
resolve: {userConfig: userConfigResolver},
loadChildren: () => import("@netway/pwa/pwa.module").then(value => value.PwaModule),
},
];
</code>
const appRoutes: Routes = [
{
path: "home",
canMatch: [platformGuard],
canActivate: [authenticationGuard],
resolve: {userConfig: userConfigResolver},
loadChildren: () => import("@netway/home/home.module").then(value => value.HomeModule),
},
{
path: "pwa",
canMatch: [platformGuard],
canActivate: [authenticationGuard],
resolve: {userConfig: userConfigResolver},
loadChildren: () => import("@netway/pwa/pwa.module").then(value => value.PwaModule),
},
];
<code>export const PwaRoutes: Routes = [
canActivate: [authenticationGuard],
loadComponent: () => import("@netway/pwa/pwa.component").then((x) => x.PwaComponent),
loadComponent: () => import("@netway/pwa/tab/home/pwa-home.component").then((x) => x.PwaHomeComponent),
canActivateChild: [authenticationChildGuard],
loadComponent: () => import("@netway/pwa/tab/home/home-main/pwa-home-main.component").then((x) => x.PwaHomeMainComponent)
loadComponent: () => import("@netway/pwa/tab/home/home-children/pwa-home-children.component").then((x) => x.PwaHomeChildrenComponent),
component: UserCustomHomeComponent,
data: {layoutName: LayoutName.HOME}
loadChildren: () => import("../process/process.module").then(p => p.ProcessModule)
loadChildren: () => import("../widget-process/widget-process.module").then(p => p.WidgetProcessModule)
title: "depositList.title",
loadChildren: () => import("../deposit-list/deposit-list.module").then(d => d.DepositListModule)
title: "depositList.actionBar.billAccount",
component: DepositBillStatementComponent
title: "loan.menu.title",
loadChildren: () => import("../loan/loan.module").then(l => l.LoanModule)
title: "cardless.page.title",
loadChildren: () => import("../cardless-cash/cardless-cash.module").then(c => c.CardlessCashModule)
<code>export const PwaRoutes: Routes = [
{
path: "",
pathMatch: "full",
redirectTo: "tab/home"
},
{
path: "tab",
canActivate: [authenticationGuard],
loadComponent: () => import("@netway/pwa/pwa.component").then((x) => x.PwaComponent),
children: [
{
path: "home",
loadComponent: () => import("@netway/pwa/tab/home/pwa-home.component").then((x) => x.PwaHomeComponent),
canActivateChild: [authenticationChildGuard],
children: [
{
path: "",
pathMatch: "full",
title: "pwa.tab.home",
loadComponent: () => import("@netway/pwa/tab/home/home-main/pwa-home-main.component").then((x) => x.PwaHomeMainComponent)
},
{
path: "page",
loadComponent: () => import("@netway/pwa/tab/home/home-children/pwa-home-children.component").then((x) => x.PwaHomeChildrenComponent),
children: [
{
path: "userCustomHome",
title: "menu.dashboard",
component: UserCustomHomeComponent,
data: {layoutName: LayoutName.HOME}
},
{
path: "process",
loadChildren: () => import("../process/process.module").then(p => p.ProcessModule)
},
{
path: "widgetProcess",
loadChildren: () => import("../widget-process/widget-process.module").then(p => p.WidgetProcessModule)
},
{
path: "depositList",
title: "depositList.title",
loadChildren: () => import("../deposit-list/deposit-list.module").then(d => d.DepositListModule)
},
{
path: "billStatements",
title: "depositList.actionBar.billAccount",
component: DepositBillStatementComponent
},
{
path: "loan",
title: "loan.menu.title",
loadChildren: () => import("../loan/loan.module").then(l => l.LoanModule)
},
{
path: "cardlessCash",
title: "cardless.page.title",
loadChildren: () => import("../cardless-cash/cardless-cash.module").then(c => c.CardlessCashModule)
},
]
}
]
},
]
}
];
</code>
export const PwaRoutes: Routes = [
{
path: "",
pathMatch: "full",
redirectTo: "tab/home"
},
{
path: "tab",
canActivate: [authenticationGuard],
loadComponent: () => import("@netway/pwa/pwa.component").then((x) => x.PwaComponent),
children: [
{
path: "home",
loadComponent: () => import("@netway/pwa/tab/home/pwa-home.component").then((x) => x.PwaHomeComponent),
canActivateChild: [authenticationChildGuard],
children: [
{
path: "",
pathMatch: "full",
title: "pwa.tab.home",
loadComponent: () => import("@netway/pwa/tab/home/home-main/pwa-home-main.component").then((x) => x.PwaHomeMainComponent)
},
{
path: "page",
loadComponent: () => import("@netway/pwa/tab/home/home-children/pwa-home-children.component").then((x) => x.PwaHomeChildrenComponent),
children: [
{
path: "userCustomHome",
title: "menu.dashboard",
component: UserCustomHomeComponent,
data: {layoutName: LayoutName.HOME}
},
{
path: "process",
loadChildren: () => import("../process/process.module").then(p => p.ProcessModule)
},
{
path: "widgetProcess",
loadChildren: () => import("../widget-process/widget-process.module").then(p => p.WidgetProcessModule)
},
{
path: "depositList",
title: "depositList.title",
loadChildren: () => import("../deposit-list/deposit-list.module").then(d => d.DepositListModule)
},
{
path: "billStatements",
title: "depositList.actionBar.billAccount",
component: DepositBillStatementComponent
},
{
path: "loan",
title: "loan.menu.title",
loadChildren: () => import("../loan/loan.module").then(l => l.LoanModule)
},
{
path: "cardlessCash",
title: "cardless.page.title",
loadChildren: () => import("../cardless-cash/cardless-cash.module").then(c => c.CardlessCashModule)
},
]
}
]
},
]
}
];
The children hirearchy in "home/page/"
are exactly the same as the ones in "pwa/tab/home/page/"
.
In my code I navigated to the pathes somehow like this: this.router.navigate("home/page/[path to the desired child])
. As you see there’s no sign of PWA path because it has been added to the source code recently.
The role of platformGuard is to redirect all the pathes from home
to pwa
when the device is a supported gadget.
Now, my question is how to route to PWA routes without modifing dozens of this.router.navigate()
absolute routing calls in my source code?
Currently, I introduced a new service and use it whenever I have to route in an absolute way:
export class PathService {
private readonly platformService = inject(PlatformService);
* @desc Use this method when you have to navigate from one module to another one.
* IMPORTANT: Don't use this method when you can solve your issue using relative routes.
* @param partialPath The raw absolute path which needs to be modified based on the current mode (NW or PWA).
* @return The modified absolute path based on the current mode as an array of strings
getAbsolute(...partialPath: ReadonlyArray<string>): Array<any> {
partialPath = this.format(...partialPath);
const pathPrefix = this.platformService.isPwaMode() ? ["pwa", "tab"] : [];
return [...pathPrefix, ...partialPath];
* @desc Removes all the route slashes and flattens the path segments to a single array
private format(...partialPath: Array<string>) {
return partialPath.flatMap(
pathSegment => pathSegment.split("/").filter(segment => segment !== "")
<code>@Injectable({
providedIn: 'root'
})
export class PathService {
private readonly platformService = inject(PlatformService);
/**
* @desc Use this method when you have to navigate from one module to another one.
*
* IMPORTANT: Don't use this method when you can solve your issue using relative routes.
* @param partialPath The raw absolute path which needs to be modified based on the current mode (NW or PWA).
* @return The modified absolute path based on the current mode as an array of strings
*/
getAbsolute(...partialPath: ReadonlyArray<string>): Array<any> {
partialPath = this.format(...partialPath);
const pathPrefix = this.platformService.isPwaMode() ? ["pwa", "tab"] : [];
return [...pathPrefix, ...partialPath];
}
/**
* @desc Removes all the route slashes and flattens the path segments to a single array
*/
private format(...partialPath: Array<string>) {
return partialPath.flatMap(
pathSegment => pathSegment.split("/").filter(segment => segment !== "")
);
}
}
</code>
@Injectable({
providedIn: 'root'
})
export class PathService {
private readonly platformService = inject(PlatformService);
/**
* @desc Use this method when you have to navigate from one module to another one.
*
* IMPORTANT: Don't use this method when you can solve your issue using relative routes.
* @param partialPath The raw absolute path which needs to be modified based on the current mode (NW or PWA).
* @return The modified absolute path based on the current mode as an array of strings
*/
getAbsolute(...partialPath: ReadonlyArray<string>): Array<any> {
partialPath = this.format(...partialPath);
const pathPrefix = this.platformService.isPwaMode() ? ["pwa", "tab"] : [];
return [...pathPrefix, ...partialPath];
}
/**
* @desc Removes all the route slashes and flattens the path segments to a single array
*/
private format(...partialPath: Array<string>) {
return partialPath.flatMap(
pathSegment => pathSegment.split("/").filter(segment => segment !== "")
);
}
}
One sample usage:
<code> this.router.navigate(
this.pathService.getAbsolute("home", "page", "kartablRegister"),
queryParams: { kartablId: kartablId, asEditing: true }
<code> this.router.navigate(
this.pathService.getAbsolute("home", "page", "kartablRegister"),
{
queryParams: { kartablId: kartablId, asEditing: true }
}
);
</code>
this.router.navigate(
this.pathService.getAbsolute("home", "page", "kartablRegister"),
{
queryParams: { kartablId: kartablId, asEditing: true }
}
);
The drawback of this solution is that I need to modify all thos this.router.navigate()
calls.
How can I achieve the same result without the need to modify my existing this.router.navigate()
calls?