From cbeeff2bd62887a683ec4d4eaa1a3588c086e7d5 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Mon, 21 Mar 2016 15:02:16 +0000 Subject: [PATCH] fix(Router): do not kill event-emitter on navigation failure Closes #7692 Closes #7532 Closes #7692 --- .../@angular/router-deprecated/src/router.ts | 10 ++++++--- .../router-deprecated/test/router_spec.ts | 21 +++++++++++++++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/modules/@angular/router-deprecated/src/router.ts b/modules/@angular/router-deprecated/src/router.ts index 3448571926..ad8c6bd5f3 100644 --- a/modules/@angular/router-deprecated/src/router.ts +++ b/modules/@angular/router-deprecated/src/router.ts @@ -276,7 +276,7 @@ export class Router { if (result) { return this.commit(instruction, _skipLocationChange) .then((_) => { - this._emitNavigationFinish(instruction.toRootUrl()); + this._emitNavigationFinish(instruction.component); return true; }); } @@ -284,9 +284,13 @@ export class Router { }); } - private _emitNavigationFinish(url): void { ObservableWrapper.callEmit(this._subject, url); } + private _emitNavigationFinish(instruction: ComponentInstruction): void { + ObservableWrapper.callEmit(this._subject, {status: 'success', instruction}); + } /** @internal */ - _emitNavigationFail(url): void { ObservableWrapper.callError(this._subject, url); } + _emitNavigationFail(url: string): void { + ObservableWrapper.callEmit(this._subject, {status: 'fail', url}); + } private _afterPromiseFinishNavigating(promise: Promise): Promise { return PromiseWrapper.catchError(promise.then((_) => this._finishNavigating()), (err) => { diff --git a/modules/@angular/router-deprecated/test/router_spec.ts b/modules/@angular/router-deprecated/test/router_spec.ts index 7569fff75c..51278fa3cf 100644 --- a/modules/@angular/router-deprecated/test/router_spec.ts +++ b/modules/@angular/router-deprecated/test/router_spec.ts @@ -135,14 +135,31 @@ export function main() { })); - it('should trigger the onError callback of a router change subscription if the URL does not match a route', + it('should pass an object containing the component instruction to the router change subscription after a successful navigation', inject([AsyncTestCompleter], (async) => { var outlet = makeDummyOutlet(); router.registerPrimaryOutlet(outlet) .then((_) => router.config([new Route({path: '/a', component: DummyComponent})])) .then((_) => { - router.subscribe((_) => {}, (url) => { + router.subscribe(({status, instruction}) => { + expect(status).toEqual('success'); + expect(instruction).toEqual(jasmine.objectContaining({urlPath: 'a', urlParams: []})); + async.done(); + }); + (location).simulateHashChange('a'); + }); + })); + + it('should pass an object containing the bad url to the router change subscription after a failed navigation', + inject([AsyncTestCompleter], (async) => { + var outlet = makeDummyOutlet(); + + router.registerPrimaryOutlet(outlet) + .then((_) => router.config([new Route({path: '/a', component: DummyComponent})])) + .then((_) => { + router.subscribe(({status, url}) => { + expect(status).toEqual('fail'); expect(url).toEqual('b'); async.done(); });