How to elegantly get full url from the ActivatedRouteSnapshot?

Radosław Roszkowiak picture Radosław Roszkowiak · May 9, 2018 · Viewed 15k times · Source

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.

enter image description here

Answer

Marc J. Schmidt picture Marc J. Schmidt · Nov 22, 2018

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