'Angular routing error cannot find parameter when redirecting to child route with parameter and outlet
I want to redirect to a child route with an outlet from a parent route with a parameter:
{
path: "projects/:projectKey",
component: ProjectComponent,
canActivate: [AuthGuard],
children: [
{ path: "artifacts", component: ArtifactsListComponent, outlet: "project-outlet", canActivate: [AuthGuard] },
{ path: "experiments", component: ExperimentsListComponent, outlet: "project-outlet", canActivate: [AuthGuard] },
{
path: "experiments/:experimentKey",
component: ExperimentDetailsComponent,
outlet: "project-outlet",
canActivate: [AuthGuard],
},
{ path: "runs", component: RunsListComponent, outlet: "project-outlet", canActivate: [AuthGuard] },
{
path: "",
redirectTo: "/projects/:projectKey/(project-outlet:experiments)",
pathMatch: "full",
},
],
},
When navigating to http://localhost:4200/projects/project-x
, I get the following error:
Error: Uncaught (in promise): Error: Cannot redirect to '/projects/:projectKey/(project-outlet:experiments)'. Cannot find ':projectKey'.
Error: Cannot redirect to '/projects/:projectKey/(project-outlet:experiments)'. Cannot find ':projectKey'.
at ApplyRedirects.findPosParam (router.js:2865)
If I navigate directly to http://localhost:4200/projects/project-x/(project-outlet:experiments)
everything works fine.
Link to stackblitz: https://stackblitz.com/edit/angular-ivy-jcdaq1?file=src/app/app-routing.module.ts
Also, if I change the redirectTo
from "/projects/:projectKey/(project-outlet:experiments)"
to a path without a parameter like "/projects/project-x/(project-outlet:experiments)"
it seems to work.
Anyone has a solution for having parameters and outlets in redirectTo path of child components?
Solution 1:[1]
I had the same problem, it because the route parameter is declared on the parent segment. you have 2 options to solve it:
- change the route of the redirect, so it will include the parameter, like this:
[{
path: "path: "/projects/:projectKey/",
redirectTo: "/projects/:projectKey/(project-outlet:experiments)",
pathMatch: "full"
},{
path: "projects/:projectKey/**",
component: ProjectComponent,
canActivate: [AuthGuard],
children: [
{ path: "artifacts", component: ArtifactsListComponent, outlet: "project-outlet", canActivate: [AuthGuard] },
{ path: "experiments", component: ExperimentsListComponent, outlet: "project-outlet", canActivate: [AuthGuard] },
{
path: "experiments/:experimentKey",
component: ExperimentDetailsComponent,
outlet: "project-outlet",
canActivate: [AuthGuard],
},
{ path: "runs", component: RunsListComponent, outlet: "project-outlet", canActivate: [AuthGuard] },
],
}]
OR 2. you can add redirect guard that you will activate when reaching the desired route, and do the redirect from there:
{
path: "projects/:projectKey",
component: ProjectComponent,
canActivate: [AuthGuard],
children: [
{
path: "experiments/:experimentKey",
component: ExperimentDetailsComponent,
outlet: "project-outlet",
canActivate: [AuthGuard],
},
{
path: "",
canActivate: [RedirectGuard]
},
],
},
class RedirectGuard {
...
canActivate() {
const { projectKey } = this.route.params;
this.router.navigateByUrl(`/projects/${projectKey}/(project-outlet:experiments)`);
}
}
you can add more logic to make it more generic and so on...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Moshe Shpitz |