I have a generic CanActivate
guard and want to alter the matrix params of the corresponding path segment (the one being tested).
With given route config:
{
path: 'parent',
canActivate: [ensureSortMatrixParamsGuard],
children: [
{ path: 'child', component: ChildComponent },
]
}
And the CanActivate
guard:
const ensureSortMatrixParamsGuard: CanActivateFn = (route, state) => {
if (!route.paramMap.has('sort')) {
const tree = // TODO -> should be `/parent;sort=asc
return tree
}
return true
}
How can I create a UrlTree
in the guard which ensures the sort
matrix param on the corresponding path segment (the one where the guard was added, =/parent
)?
With the following solution I can access the url segment - but only in way that works for the case, when this route is accessed directly (not one of its children; the corresponding segment would not be the last one then).
const tree = inject(Router).parseUrl(state.url)
const primarySegments = tree.root.children[PRIMARY_OUTLET].segments
const lastPrimarySegment = primarySegments[primarySegments.length - 1]
// then add the matrix param and then return the `tree`
lastPrimarySegment.parameters['sort'] = 'asc'
How can I conclude which segment of the UrlTree
corresponds with the RouteSnapshot
?
I found a way that seems to work:
/**
* returns all the parent ARS and provided ARS in an array
* e.g. [ars.parent.parent, ars.parent, ars]
*/
function anchestorRouteSnapshots(ars: ActivatedRouteSnapshot | null): ActivatedRouteSnapshot[] {
return ars ? [...anchestorRouteSnapshots(ars.parent), ars] : []
}
const anchestors = anchestorRouteSnapshots(route)
.map((ars) => ars.routeConfig)
.filter((rc) => !!rc && rc.path !== '') // there might be ARS without routeConfig (e.g. AppRoot) or with an empty path part
// this is the segment from the UrlTree I want to add the matrix param
const segment = primarySegments[anchestors.length - 1]
See working Stackblitz :)