In some of my Angular route guards, I want to set up the "next" path, to redirect to after successful login.
So, the ordinary guard canActivate
function signature looks like this:
public canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | boolean {
// ...blah
return true;
}
The route
parameter is an instance of ActivatedRouteSnapshot
.
Previously to get the "next" URL I was just getting it from the route.url
. This works just fine, as long as there are no children routes.
My example URL is /search/advanced?query_hash=1221d3b57f5616ee16ce70fdc78907ab
, where advanced
is a child route of a search
.
Child routes can be found in route.children
, but iterating over these children (especially there might be multiple levels) and combining the URL this way seems awkward and ugly.
What I'm interested in is contained in route._routerState.url
property (being a string, on the bottom of the image below), but it's a "private" variable.
Am I missing something? How can one elegantly get the full (with children paths) URL from the ActivatedRouteSnapshot
? Angular version is 5.1.
There's no ready to use function from Angular router to achieve that, so I wrote them:
function getResolvedUrl(route: ActivatedRouteSnapshot): string {
return route.pathFromRoot
.map(v => v.url.map(segment => segment.toString()).join('/'))
.join('/');
}
function getConfiguredUrl(route: ActivatedRouteSnapshot): string {
return '/' + route.pathFromRoot
.filter(v => v.routeConfig)
.map(v => v.routeConfig!.path)
.join('/');
}
Example output when route
is from ProjectComponent
:
const routes: Routes = [
{
path: 'project', component: ProjectListComponent, children: [
{path: ':id', component: ProjectComponent}
]
},
];
getResolvedUrl(route) => /project/id1
getConfiguredUrl(route) => /project/:id