Skip to content

Instantly share code, notes, and snippets.

@matanshukry
Created February 7, 2017 23:16
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save matanshukry/22fae5dba9c307baf0f364a9c9f7c115 to your computer and use it in GitHub Desktop.
Save matanshukry/22fae5dba9c307baf0f364a9c9f7c115 to your computer and use it in GitHub Desktop.
/**
* Copyright (c) Matan Shukry
* All rights reserved.
*/
import { UrlSegment, UrlSegmentGroup, Route } from '@angular/router';
// export type UrlMatchResult = {
// consumed: UrlSegment[]; posParams?: { [name: string]: UrlSegment };
// };
export function ComplexUrlMatcher(paramName: string, regex: RegExp) {
return (
segments: UrlSegment[],
segmentGroup: UrlSegmentGroup,
route: Route) => {
const parts = [regex];
const posParams: { [key: string]: UrlSegment } = {};
const consumed: UrlSegment[] = [];
let currentIndex = 0;
for (let i = 0; i < parts.length; ++i) {
if (currentIndex >= segments.length) {
return null;
}
const current = segments[currentIndex];
const part = parts[i];
if (!part.test(current.path)) {
return null;
}
posParams[paramName] = current;
consumed.push(current);
currentIndex++;
}
if (route.pathMatch === 'full' &&
(segmentGroup.hasChildren() || currentIndex < segments.length)) {
return null;
}
return { consumed, posParams };
}
}
/**
* Copyright (c) Matan Shukry
* All rights reserved.
*/
export const UserRoutes: Routes = [
{
path: 'users',
component: UserComponent,
children: [
{
path: '',
component: UserListComponent
},
{
matcher: ComplexUrlMatcher("id", /[0-9]+/),
component: UserItemComponent
},
]
}
];
@NgModule({
imports: [RouterModule.forChild(UserRoutes)],
exports: [RouterModule]
})
export class UserRoutingModule { }
@ronaksharma8
Copy link

ronaksharma8 commented May 22, 2017

@matanshukry :- i have replicated your code into my demo project.... but it shows error "Expression form not supported" while building project , currently i am using lastest version of angular i,e angular4... can you please guide me if i am misssing something.

My requirement is as follows :-

../xyz/abc/file/asd/dsa/das
../xyz/abc/file/qwe/dfg/yrf

if url contains "file" word, it should redirect to specific component.

@peinearydevelopment
Copy link

@matanshukry I'm experiencing the same issue as @ronaksharma8 and am just as stumped as to what to do. Any help would be greatly appreciated!!!

@ubaidazad
Copy link

getting following error.

Type '{ path: string; children: ({ path: string; loadChildren: string; } | { path: string; canActivate:...' is not assignable to type 'Route[]'.
Type '{ path: string; children: ({ path: string; loadChildren: string; } | { path: string; canActivate:...' is not assignable to type 'Route'.
Types of property 'children' are incompatible.
Type '({ path: string; loadChildren: string; } | { path: string; canActivate: typeof AuthGuard[]; loadC...' is not assignable to type 'Route[] | undefined'.
Type '({ path: string; loadChildren: string; } | { path: string; canActivate: typeof AuthGuard[]; loadC...' is not assignable to type 'Route[]'.
Type '{ path: string; loadChildren: string; } | { path: string; canActivate: typeof AuthGuard[]; loadCh...' is not assignable to type 'Route'.
Type '{ matcher: (segments: UrlSegment[], segmentGroup: UrlSegmentGroup, route: Route) => { consumed: U...' is not assignable to type 'Route'.
Types of property 'matcher' are incompatible.
Type '(segments: UrlSegment[], segmentGroup: UrlSegmentGroup, route: Route) => { consumed: UrlSegment[]...' is not assignable to type 'UrlMatcher | undefined'.
Type '(segments: UrlSegment[], segmentGroup: UrlSegmentGroup, route: Route) => { consumed: UrlSegment[]...' is not assignable to type 'UrlMatcher'.
Type '{ consumed: UrlSegment[]; posParams: { [key: string]: UrlSegment; }; } | null' is not assignable to type 'UrlMatchResult'.
Type 'null' is not assignable to type 'UrlMatchResult'.

@pranabunni
Copy link

@matanshukry i also facing same issue.how can i solve it?

@sajagporwal123
Copy link

sajagporwal123 commented May 25, 2018

@matanshukry i am also facing same issue
ERROR in app/app-routing.module.ts(120,49): Error during template compile of 'AppRoutingModule' Expression form not supported.
when i am making production build . i am using angular 5

@xavadu
Copy link

xavadu commented Feb 2, 2021

For mine use case where a matcher can have optionally parameter

/**
 * Generic matcher function
 *
 * Set in route data variable with a named regex to get parameters
 * ie:
 * data: {
 *     regex: /^(?<currency_pair>[a-z_]{3,6}-[a-z_]{3,6})?$/
 * }
 */
export function matcher(segments: UrlSegment[], segmentGroup: UrlSegmentGroup, route: Route): UrlMatchResult {
    const regex = route.data.regex;
    const url = segments.length == 1 ? segments[0].toString() : '';

    let params = url.match(regex);
    if (params) {
        const posParams: { [key: string]: UrlSegment } = {};

        // Named parameter based in name group of regexp
        for (const [name, value] of Object.entries(params.groups)) {
            posParams[name] = new UrlSegment(value, {});;
        }

        return { consumed: segments, posParams };
    }

    return null;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment