I'm trying to configure a set of routes where the top level URL in a module should redirect users to an alternate path in the same module based on their current permissions. I think I should be able to accomplish what I want by using the redirectTo
parameter and a canMatch
guard.
This is an example of the functionality I want. In this scenario I have a menu that directs users to a "members" list module. Based on their permissions, I want the user to see either all app members (they are an admin), or just their own team (they own teams).
What I expect to happen is that if they are not an admin, the first path will fail to match, and so the redirect will be ignored. The second empty pattern will be tried, it will pass the "canMatch" guard, and then the redirect will be processed. The user will then be redirected to "./teams".
Instead, what I'm seeing is the first redirectTo
being processed no matter what the result of the guard is.
const routes: Routes = [
{
path: '',
redirectTo: 'all',
pathMatch: 'full',
canMatch: [AdminGuard],
},
{
path: '',
redirectTo: 'teams',
pathMatch: 'full',
canMatch: [TeamOwnerGuard],
},
{
path: 'all',
pathMatch: 'full',
component: AllMembersListComponent,
},
{
path: 'teams',
pathMatch: 'full',
component: TeamMembersListComponent,
},
{
path: '**',
component: NotFoundComponent,
},
];
@NgModule({
imports: [
RouterModule.forChild(routes),
],
})
export class TeamMembersModule {}
Documentation
redirectTo: "A URL to redirect to when the path matches."
canMatch: "An array of CanMatchFn or DI tokens used to look up CanMatch() handlers, in order to determine if the current user is allowed to match the Route. "
Update
Update for anyone else that ends up here. As of Angular 15, redirectTo
is evaluated before any route guards, and so what I was attempting in the original question will not work.
Solution
The solution that worked for me was to build a canActivate
guard that returns a UrlTree on the base route. The UrlTree redirects to an alternate route based on permissions.
The solution is moving the canMatch routes to the final routes.
For the tests I have run:
Here is my example app: Stackblitz