Skip to content

Commit 7236de8

Browse files
btfordgoderbauer
authored andcommitted
fix(router): throw when component in route config is not defined
Close angular#3265 Closes angular#3569
1 parent ab8b6ba commit 7236de8

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

modules/angular2/src/router/route_registry.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,17 @@ import {
1919
isFunction,
2020
StringWrapper,
2121
BaseException,
22+
Type,
2223
getTypeNameForDebugging
2324
} from 'angular2/src/facade/lang';
24-
import {RouteConfig, AsyncRoute, Route, Redirect, RouteDefinition} from './route_config_impl';
25+
import {
26+
RouteConfig,
27+
AsyncRoute,
28+
Route,
29+
AuxRoute,
30+
Redirect,
31+
RouteDefinition
32+
} from './route_config_impl';
2533
import {reflector} from 'angular2/src/reflection/reflection';
2634
import {Injectable} from 'angular2/di';
2735
import {normalizeRouteConfig} from './route_config_nomalizer';
@@ -44,6 +52,13 @@ export class RouteRegistry {
4452
config(parentComponent: any, config: RouteDefinition): void {
4553
config = normalizeRouteConfig(config);
4654

55+
// this is here because Dart type guard reasons
56+
if (config instanceof Route) {
57+
assertComponentExists(config.component, config.path);
58+
} else if (config instanceof AuxRoute) {
59+
assertComponentExists(config.component, config.path);
60+
}
61+
4762
var recognizer: RouteRecognizer = this._rules.get(parentComponent);
4863

4964
if (isBlank(recognizer)) {
@@ -269,3 +284,9 @@ function assertTerminalComponent(component, path) {
269284
}
270285
}
271286
}
287+
288+
function assertComponentExists(component: Type, path: string): void {
289+
if (!isType(component)) {
290+
throw new BaseException(`Component for route "${path}" is not defined, or is not a class.`);
291+
}
292+
}

modules/angular2/test/router/route_config_spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {Component, Directive, View} from 'angular2/annotations';
1616
import {DOM} from 'angular2/src/dom/dom_adapter';
1717
import {bind} from 'angular2/di';
1818
import {DOCUMENT_TOKEN} from 'angular2/src/render/render';
19+
import {Type} from 'angular2/src/facade/lang';
1920

2021
import {
2122
routerInjectables,

modules/angular2/test/router/route_registry_spec.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ import {
77
expect,
88
inject,
99
beforeEach,
10-
SpyObject
10+
SpyObject,
11+
IS_DARTIUM
1112
} from 'angular2/test_lib';
1213

1314
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
15+
import {Type} from 'angular2/src/facade/lang';
1416

1517
import {RouteRegistry} from 'angular2/src/router/route_registry';
16-
import {RouteConfig, Route, AsyncRoute} from 'angular2/src/router/route_config_decorator';
18+
import {RouteConfig, Route, AuxRoute, AsyncRoute} from 'angular2/src/router/route_config_decorator';
1719
import {stringifyInstruction} from 'angular2/src/router/instruction';
1820

1921
export function main() {
@@ -185,6 +187,20 @@ export function main() {
185187
.toThrowError('Unexpected "..." before the end of the path for "home/.../fun/".');
186188
});
187189

190+
191+
it('should throw if a config has a component that is not defined', () => {
192+
expect(() => registry.config(RootHostCmp, new Route({path: '/', component: null})))
193+
.toThrowError('Component for route "/" is not defined, or is not a class.');
194+
expect(() => registry.config(RootHostCmp, new AuxRoute({path: '/', component: null})))
195+
.toThrowError('Component for route "/" is not defined, or is not a class.');
196+
197+
// This would never happen in Dart
198+
if (!IS_DARTIUM) {
199+
expect(() => registry.config(RootHostCmp, new Route({path: '/', component:<Type>(<any>4)})))
200+
.toThrowError('Component for route "/" is not defined, or is not a class.');
201+
}
202+
});
203+
188204
it('should match matrix params on child components and query params on the root component',
189205
inject([AsyncTestCompleter], (async) => {
190206
registry.config(RootHostCmp, new Route({path: '/first/...', component: DummyParentCmp}));

0 commit comments

Comments
 (0)