I have an order section in my app:
RouterModule.forChild([
{
path: '',
component: OrderComponent,
canActivate: [OrderGuard],
children: [
{
path: '',
component: OrderInfoComponent
},
{
path: 'approved',
component: OrderApprovedComponent
},
{
path: 'declined',
component: OrderDeclinedComponent
}
]
}
])
I have to redirect the user to the appropriate page depending on the order state. I created a guard:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): UrlTree {
const order = ...; // Imagine we fetch the order here...
let path: string;
switch (order.state) {
case OrderState.Default:
path = '';
break;
case OrderState.Approved:
path = 'approved';
break;
case OrderState.Declined:
path = 'declined';
break;
}
return this.router.parseUrl(`${state.url}/${path}`);
}
That's what's happening (for order.state === 'approved'
):
- The user goes to
/order
. - Guard redirects the user to
/order/approved
. - The user is on
/order/approved
. - Guard redirects the user to
/order/approved/approved
. - The error
Cannot match any routes
is being thrown.
In other words, it goes into infinite loop. How can I break it? I was looking at this solution, but it leaves the skip
query parameter after the redirection and it does not work with UrlTree since we cannot pass any query parameters.
I also want to redirect the user properly if they went to a child route (/declined
or /approved
).