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

Tags:

Angular