Skip to content

Commit 8f2fa0f

Browse files
committed
fix(router): disallow component routes with named outlets
Closes #11208, #11082
1 parent fc60fa7 commit 8f2fa0f

3 files changed

Lines changed: 20 additions & 3 deletions

File tree

‎modules/@angular/router/src/config.ts‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import {Type} from '@angular/core';
1010
import {Observable} from 'rxjs/Observable';
11-
11+
import {PRIMARY_OUTLET} from './shared';
1212

1313
/**
1414
* @whatItDoes Represents router configuration.
@@ -320,6 +320,10 @@ function validateNode(route: Route): void {
320320
if (Array.isArray(route)) {
321321
throw new Error(`Invalid route configuration: Array cannot be specified`);
322322
}
323+
if (route.component === undefined && (route.outlet && route.outlet !== PRIMARY_OUTLET)) {
324+
throw new Error(
325+
`Invalid route configuration of route '${route.path}': a componentless route cannot have a named outlet set`);
326+
}
323327
if (!!route.redirectTo && !!route.children) {
324328
throw new Error(
325329
`Invalid configuration of route '${route.path}': redirectTo and children cannot be used together`);

‎modules/@angular/router/src/directives/router_outlet.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import {RouterOutletMap} from '../router_outlet_map';
1212
import {ActivatedRoute} from '../router_state';
1313
import {PRIMARY_OUTLET} from '../shared';
1414

15-
16-
1715
/**
1816
* @whatItDoes Acts as a placeholder that Angular dynamically fills based on the current router
1917
* state.
@@ -79,6 +77,10 @@ export class RouterOutlet implements OnDestroy {
7977
activatedRoute: ActivatedRoute, loadedResolver: ComponentFactoryResolver,
8078
loadedInjector: Injector, providers: ResolvedReflectiveProvider[],
8179
outletMap: RouterOutletMap): void {
80+
if (this.isActivated) {
81+
throw new Error('Cannot activate an already activated outlet');
82+
}
83+
8284
this.outletMap = outletMap;
8385
this._activatedRoute = activatedRoute;
8486

‎modules/@angular/router/test/config.spec.ts‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import {validateConfig} from '../src/config';
10+
import {PRIMARY_OUTLET} from '../src/shared';
1011

1112
describe('config', () => {
1213
describe('validateConfig', () => {
@@ -80,6 +81,16 @@ describe('config', () => {
8081
.toThrowError(
8182
/Invalid configuration of route 'a': pathMatch can only be set to 'prefix' or 'full'/);
8283
});
84+
85+
it('should throw when pathPatch is invalid', () => {
86+
expect(() => { validateConfig([{path: 'a', outlet: 'aux', children: []}]); })
87+
.toThrowError(
88+
/Invalid route configuration of route 'a': a componentless route cannot have a named outlet set/);
89+
90+
expect(() => validateConfig([{path: 'a', outlet: '', children: []}])).not.toThrow();
91+
expect(() => validateConfig([{path: 'a', outlet: PRIMARY_OUTLET, children: []}]))
92+
.not.toThrow();
93+
});
8394
});
8495
});
8596

0 commit comments

Comments
 (0)