Skip to content

Commit

Permalink
feat(router): enable parent chain unknown route handlers
Browse files Browse the repository at this point in the history
bubble up the current router parent chain for the first defined unknown
route handler if one does not exists on the current router

feature #443
  • Loading branch information
jagonalez committed Feb 24, 2017
1 parent ccb4479 commit f692bcb
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 9 deletions.
22 changes: 13 additions & 9 deletions src/navigation-instruction.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface NavigationInstructionInit {

export class CommitChangesStep {
run(navigationInstruction: NavigationInstruction, next: Function) {

return navigationInstruction._commitChanges(true).then(() => {
navigationInstruction._updateTitle();
return next();
Expand Down Expand Up @@ -213,17 +214,20 @@ export class NavigationInstruction {
}

if (viewPortInstruction.strategy === activationStrategy.replace) {
if (waitToSwap) {
delaySwaps.push({viewPort, viewPortInstruction});
}

loads.push(viewPort.process(viewPortInstruction, waitToSwap).then((x) => {
if (viewPortInstruction.childNavigationInstruction) {
return viewPortInstruction.childNavigationInstruction._commitChanges();
if (viewPortInstruction.childNavigationInstruction && viewPortInstruction.childNavigationInstruction.parentCatchHandler) {
loads.push(viewPortInstruction.childNavigationInstruction._commitChanges());
} else {
if (waitToSwap) {
delaySwaps.push({viewPort, viewPortInstruction});
}
loads.push(viewPort.process(viewPortInstruction, waitToSwap).then((x) => {
if (viewPortInstruction.childNavigationInstruction) {
return viewPortInstruction.childNavigationInstruction._commitChanges();
}

return undefined;
}));
return undefined;
}));
}
} else {
if (viewPortInstruction.childNavigationInstruction) {
loads.push(viewPortInstruction.childNavigationInstruction._commitChanges(waitToSwap));
Expand Down
36 changes: 36 additions & 0 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -435,11 +435,47 @@ export class Router {
}));

return evaluateNavigationStrategy(instruction, this.catchAllHandler);
} else if (this.parent) {
let router = this._parentCatchAllHandler(this.parent);

if (router) {
let newParentInstruction = this._findParentInstructionFromRouter(router, parentInstruction);

let instruction = new NavigationInstruction(Object.assign({}, instructionInit, {
params: { path: fragment },
queryParams: results && results.queryParams,
router: router,
parentInstruction: newParentInstruction,
parentCatchHandler: true,
config: null // config will be created by the chained parent catchAllHandler
}));

return evaluateNavigationStrategy(instruction, router.catchAllHandler)
}
}

return Promise.reject(new Error(`Route not found: ${url}`));
}

_findParentInstructionFromRouter(router: Router, instruction: NavigationInstruction): NavigationInstruction {
if (instruction.router === router) {
instruction.fragment = router.baseUrl; //need to change the fragment in case of a redirect instead of moduleId
return instruction;
} else if (instruction.parentInstruction) {
return this._findParentInstructionFromRouter(router, instruction.parentInstruction)
}
return undefined;
}

_parentCatchAllHandler(router): Function|Boolean {
if (router.catchAllHandler) {
return router;
} else if (router.parent) {
return this._parentCatchAllHandler(router.parent);
}
return false;
}

_createRouteConfig(config, instruction) {
return Promise.resolve(config)
.then(c => {
Expand Down
28 changes: 28 additions & 0 deletions test/router.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,34 @@ describe('the router', () => {
describe('catchAllHandler', () => {
let expectedInstructionShape = jasmine.objectContaining({ config: jasmine.objectContaining({ moduleId: 'test' }) });

it('should use a parent routers catchAllHandler if one exists', (done) => {
const child = router.createChild(new Container());
child.baseUrl = 'empty';
let expectedFirstInstructionShape = jasmine.objectContaining({ config: jasmine.objectContaining({ moduleId: './empty' }) });
let expectedSecondInstructionShape = jasmine.objectContaining({ config: jasmine.objectContaining({ moduleId: 'test' }) });
Promise.all([
router.configure(config => {
config.unknownRouteConfig = 'test';
config.mapRoute({route: 'foo', moduleId: './empty'})
}),
child.configure(config => {
config.map([
{ name: 'empty', route: '', moduleId: './child-empty' }
]);
})
])
.then(() => {
return router._createNavigationInstruction('foo/bar/123?bar=456')
.then(x => {
expect(x).toEqual(expectedFirstInstructionShape)
return child._createNavigationInstruction('bar/123?bar=456', x)
.then(x1 => expect(x1).toEqual(expectedInstructionShape))
});
})
.catch(reason => expect(true).toBeFalsy('should have succeeded', reason))
.then(done);
});

it('should use string moduleId handler', (done) => {
router
.configure(config => {
Expand Down

0 comments on commit f692bcb

Please sign in to comment.