fix(router): resolve and guards should be able to reject with null and undefined (#19418)

Closes #17148
This commit is contained in:
Victor Savkin 2017-09-28 14:06:08 -04:00 committed by Victor Berchet
parent ff5b050a92
commit a9d32a3f89
5 changed files with 26 additions and 9 deletions

View File

@ -47,7 +47,7 @@ export class PreActivation {
private future: RouterStateSnapshot, private curr: RouterStateSnapshot,
private moduleInjector: Injector, private forwardEvent?: (evt: Event) => void) {}
initalize(parentContexts: ChildrenOutletContexts): void {
initialize(parentContexts: ChildrenOutletContexts): void {
const futureRoot = this.future._root;
const currRoot = this.curr ? this.curr._root : null;
this.setupChildRouteGuards(futureRoot, currRoot, parentContexts, [futureRoot.value]);

View File

@ -625,7 +625,7 @@ export class Router {
preActivation = new PreActivation(
snapshot, this.routerState.snapshot, moduleInjector,
(evt: Event) => this.triggerEvent(evt));
preActivation.initalize(this.rootContexts);
preActivation.initialize(this.rootContexts);
return {appliedUrl, snapshot};
});

View File

@ -104,7 +104,7 @@ export function navigationCancelingError(message: string) {
}
export function isNavigationCancelingError(error: Error) {
return (error as any)[NAVIGATION_CANCELING_ERROR];
return error && (error as any)[NAVIGATION_CANCELING_ERROR];
}
// Matches the route configuration (`route`) against the actual URL (`segments`).

View File

@ -953,6 +953,7 @@ describe('Integration', () => {
{provide: 'resolveFour', useValue: (a: any, b: any) => 4},
{provide: 'resolveSix', useClass: ResolveSix},
{provide: 'resolveError', useValue: (a: any, b: any) => Promise.reject('error')},
{provide: 'resolveNullError', useValue: (a: any, b: any) => Promise.reject(null)},
{provide: 'numberOfUrlSegments', useValue: (a: any, b: any) => a.url.length},
]
});
@ -1020,6 +1021,22 @@ describe('Integration', () => {
expect(e).toEqual('error');
})));
it('should handle empty errors', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp);
router.resetConfig(
[{path: 'simple', component: SimpleCmp, resolve: {error: 'resolveNullError'}}]);
const recordedEvents: any[] = [];
router.events.subscribe(e => e instanceof RouterEvent && recordedEvents.push(e));
let e: any = 'some value';
router.navigateByUrl('/simple').catch(error => e = error);
advance(fixture);
expect(e).toEqual(null);
})));
it('should preserve resolved data', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp);

View File

@ -107,7 +107,7 @@ describe('Router', () => {
'url', new TreeNode(empty.root, [new TreeNode(childSnapshot, [])]));
const p = new PreActivation(futureState, empty, TestBed, (evt) => { events.push(evt); });
p.initalize(new ChildrenOutletContexts());
p.initialize(new ChildrenOutletContexts());
p.checkGuards().subscribe((x) => result = x, (e) => { throw e; });
expect(result).toBe(true);
expect(events.length).toEqual(2);
@ -140,7 +140,7 @@ describe('Router', () => {
])]));
const p = new PreActivation(futureState, empty, TestBed, (evt) => { events.push(evt); });
p.initalize(new ChildrenOutletContexts());
p.initialize(new ChildrenOutletContexts());
p.checkGuards().subscribe((x) => result = x, (e) => { throw e; });
expect(result).toBe(true);
@ -173,7 +173,7 @@ describe('Router', () => {
const p =
new PreActivation(futureState, currentState, TestBed, (evt) => { events.push(evt); });
p.initalize(new ChildrenOutletContexts());
p.initialize(new ChildrenOutletContexts());
p.checkGuards().subscribe((x) => result = x, (e) => { throw e; });
expect(result).toBe(true);
@ -219,7 +219,7 @@ describe('Router', () => {
const p =
new PreActivation(futureState, currentState, TestBed, (evt) => { events.push(evt); });
p.initalize(new ChildrenOutletContexts());
p.initialize(new ChildrenOutletContexts());
p.checkGuards().subscribe((x) => result = x, (e) => { throw e; });
expect(result).toBe(true);
@ -497,7 +497,7 @@ describe('Router', () => {
function checkResolveData(
future: RouterStateSnapshot, curr: RouterStateSnapshot, injector: any, check: any): void {
const p = new PreActivation(future, curr, injector);
p.initalize(new ChildrenOutletContexts());
p.initialize(new ChildrenOutletContexts());
p.resolveData().subscribe(check, (e) => { throw e; });
}
@ -505,6 +505,6 @@ function checkGuards(
future: RouterStateSnapshot, curr: RouterStateSnapshot, injector: any,
check: (result: boolean) => void): void {
const p = new PreActivation(future, curr, injector);
p.initalize(new ChildrenOutletContexts());
p.initialize(new ChildrenOutletContexts());
p.checkGuards().subscribe(check, (e) => { throw e; });
}