angular routing multiple paths to same component
Building on CornelC's answer, I wrote a method that accepts an array of string as paths and spits out a url matcher that will match an element of the array:
export const routingMatcher: ((paths: string[]) => UrlMatcher) = (paths: string[]) => {
const result: UrlMatcher = (segments) => {
const matchingPathIndex = paths.findIndex((path, index) => {
const pathSegments = path.split("/");
return segments.every((segment, i) =>
pathSegments.length > i && (
pathSegments[i].startsWith(":") ? true : segment.path.toLowerCase() === pathSegments[i].toLowerCase()));
});
if (matchingPathIndex >= 0) {
const matchingPath = paths[matchingPathIndex];
const consumed: UrlSegment[] = [];
const params = {};
matchingPath.split("/").forEach((path, i) => {
consumed.push(segments[i]);
if (path.startsWith(":")) {
const param = path.substring(1);
params[param] = segments[i];
}
});
return {
consumed: consumed,
posParams: params
};
}
return null;
};
return result;
};
You can use it like this in your routing definitions:
children: [
// excluding the other paths for brevity
matcher: routingMatcher(['today', 'tomorrow', 'expired'])
component: AccessRequestsComponent
}))
]
You can use a mapped array:
children: [
// excluding the other paths for brevity
...['today', 'tomorrow', 'expired'].map(path => ({
path,
component: AccessRequestsComponent
}))
]
You can use the UrlMatcher property.
{
path: 'access-requests',
canActivate: [AccessGuard],
component: AccessRequestsComponent,
children: [
{
path: '',
redirectTo: 'today',
pathMatch: 'full'
},
{
matcher: matcherFunction,
component: AccessRequestsComponent
}
]
}
And
export function matcherFunction(url: UrlSegment[]) {
if (url.length == 1) {
const path = url[0].path;
if(path.startsWith('today')
|| path.startsWith('tomorrow')
|| path.startsWith('expired')){
return {consumed: url};
}
}
return null;
}
Note: Untested code