Skip to content

Commit 8aec215

Browse files
committed
fix(router): throw when generating non-terminal link
Closes angular#3979 Closes angular#4092
1 parent f91c087 commit 8aec215

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

modules/angular2/src/router/route_registry.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ export class RouteRegistry {
200200
generate(linkParams: any[], parentComponent: any): Instruction {
201201
let segments = [];
202202
let componentCursor = parentComponent;
203+
var lastInstructionIsTerminal = false;
203204

204205
for (let i = 0; i < linkParams.length; i += 1) {
205206
let segment = linkParams[i];
@@ -233,9 +234,26 @@ export class RouteRegistry {
233234
}
234235
segments.push(response);
235236
componentCursor = response.componentType;
237+
lastInstructionIsTerminal = response.terminal;
236238
}
237239

238-
var instruction: Instruction = this._generateRedirects(componentCursor);
240+
var instruction: Instruction = null;
241+
242+
if (!lastInstructionIsTerminal) {
243+
instruction = this._generateRedirects(componentCursor);
244+
245+
if (isPresent(instruction)) {
246+
let lastInstruction = instruction;
247+
while (isPresent(lastInstruction.child)) {
248+
lastInstruction = lastInstruction.child;
249+
}
250+
lastInstructionIsTerminal = lastInstruction.component.terminal;
251+
}
252+
if (!lastInstructionIsTerminal) {
253+
throw new BaseException(
254+
`Link "${ListWrapper.toJSON(linkParams)}" does not resolve to a terminal instruction.`);
255+
}
256+
}
239257

240258

241259
while (segments.length > 0) {

modules/angular2/test/router/route_registry_spec.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,8 @@ export function main() {
7979
expect(url).toEqual('first/one/second/two');
8080
});
8181

82-
it('should geneate params as an empty StringMap when no params are given', () => {
83-
registry.config(RootHostCmp,
84-
new Route({path: '/test/...', component: DummyParentParamCmp, as: 'test'}));
82+
it('should generate params as an empty StringMap when no params are given', () => {
83+
registry.config(RootHostCmp, new Route({path: '/test', component: DummyCmpA, as: 'test'}));
8584
var instruction = registry.generate(['test'], RootHostCmp);
8685
expect(instruction.component.params).toEqual({});
8786
});
@@ -232,6 +231,13 @@ export function main() {
232231
}
233232
});
234233

234+
it('should throw when linkParams are not terminal', () => {
235+
registry.config(RootHostCmp,
236+
new Route({path: '/first/...', component: DummyParentCmp, as: 'first'}));
237+
expect(() => { registry.generate(['first'], RootHostCmp); })
238+
.toThrowError('Link "["first"]" does not resolve to a terminal instruction.');
239+
});
240+
235241
it('should match matrix params on child components and query params on the root component',
236242
inject([AsyncTestCompleter], (async) => {
237243
registry.config(RootHostCmp, new Route({path: '/first/...', component: DummyParentCmp}));

0 commit comments

Comments
 (0)