I'm trying to make an UrlMatcher factory
export const dummyMatcher: UrlMatcher = matchUrlFn(sitemap as any, 'dummy');
export const routes: Routes = [
{ matcher: dummyMatcher, component: DummyComponent },
{ path: '**', component: DummyComponent },
];
But this doesn't work with AoT... How do we handle function factories with AoT?
I tried
export function dummyMatcher(): UrlMatcher { return routeMatcher(sitemap as any, 'dummy'); }
but compiler is complaining:
Type '{ matcher: () => UrlMatcher; component: typeof DummyComponent; }...' is not assignable to type 'Route[]'.
Use case:
I need to match web pages (described in NavigationNode[]
) and render them in specific template components. Page can have multiple urls (for migration purposes, localized urls, etc.).
Here's the matching logic:
import { UrlSegment, UrlSegmentGroup, Route, UrlMatchResult } from '@angular/router';
import { inArray } from '@core/utils';
export interface NavigationNode {
...
title?: string;
template?: string;
urls?: string[];
}
/**
* https://angular.io/api/router/UrlMatcher
*/
export const UrlMatcherFactory = (conditions) =>
(segments: UrlSegment[], group: UrlSegmentGroup, route: Route): UrlMatchResult =>
conditions(segments) ? ({ consumed: segments }) : null;
export const matchUrl = (nodes: NavigationNode[], template?: string) =>
(segments: UrlSegment[]) => nodes
.filter(node => template ? node.template === template : true)
.some(node => inArray(node.urls)(`/${segments.join('/')}`));
export const matchUrlFn= (nodes: NavigationNode[], template?: string) =>
UrlMatcherFactory(matchUrl(nodes, template));
This can be easily extended to use different matching, for example Regex:
export const matchRegex = (nodes: NavigationNode[]) =>
(segments: UrlSegment[]) => nodes
.some(node => /\w+\/xyz/\d{1, 3}/.test(node.title)); /* bad example (: */
export const matchRegexFn = (nodes: NavigationNode[], template?: string) =>
UrlMatcherFactory(matchRegex(nodes));
matcher
property should implement UrlMatcher
type:
export declare type UrlMatcher = (segments: UrlSegment[], group: UrlSegmentGroup, route: Route) => UrlMatchResult;
so i would suggest you to change code like:
export function dummyMatcher(segments: UrlSegment[], group: UrlSegmentGroup, route: Route): UrlMatchResult {
const factory = matchUrlFn(sitemap as any, 'dummy');
return factory(segments, group, route);
}