From c767df0e4ead52da571a731d70aa402245064aea Mon Sep 17 00:00:00 2001 From: vsavkin Date: Thu, 1 Dec 2016 15:46:22 -0800 Subject: [PATCH] fix(router): throw a better error message when angular 1 is not bootstraped --- modules/@angular/router/test/router.spec.ts | 27 ++++++-------- modules/@angular/router/upgrade.ts | 41 ++++++++++++++++----- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/modules/@angular/router/test/router.spec.ts b/modules/@angular/router/test/router.spec.ts index 3d11389560..bdd2ac2725 100644 --- a/modules/@angular/router/test/router.spec.ts +++ b/modules/@angular/router/test/router.spec.ts @@ -7,7 +7,7 @@ */ import {Location} from '@angular/common'; -import {TestBed} from '@angular/core/testing'; +import {TestBed, inject} from '@angular/core/testing'; import {ResolveData} from '../src/config'; import {PreActivation, Router} from '../src/router'; @@ -36,23 +36,20 @@ describe('Router', () => { describe('setUpLocationChangeListener', () => { beforeEach(() => { TestBed.configureTestingModule({imports: [RouterTestingModule]}); }); - it('should be indempotent', () => { - const r: Router = TestBed.get(Router); - const location: Location = TestBed.get(Location); + it('should be indempotent', inject([Router, Location], (r: Router, location: Location) => { + r.setUpLocationChangeListener(); + const a = (r).locationSubscription; + r.setUpLocationChangeListener(); + const b = (r).locationSubscription; - r.setUpLocationChangeListener(); - const a = (r).locationSubscription; - r.setUpLocationChangeListener(); - const b = (r).locationSubscription; + expect(a).toBe(b); - expect(a).toBe(b); + r.dispose(); + r.setUpLocationChangeListener(); + const c = (r).locationSubscription; - r.dispose(); - r.setUpLocationChangeListener(); - const c = (r).locationSubscription; - - expect(c).not.toBe(b); - }); + expect(c).not.toBe(b); + })); }); describe('PreActivation', () => { diff --git a/modules/@angular/router/upgrade.ts b/modules/@angular/router/upgrade.ts index 10b61c04ae..c4ab90fe1c 100644 --- a/modules/@angular/router/upgrade.ts +++ b/modules/@angular/router/upgrade.ts @@ -40,10 +40,20 @@ export const RouterUpgradeInitializer = { deps: [UpgradeModule, ApplicationRef, RouterPreloader, ROUTER_CONFIGURATION] }; +/** + * @internal + */ export function initialRouterNavigation( ngUpgrade: UpgradeModule, ref: ApplicationRef, preloader: RouterPreloader, opts: ExtraOptions): Function { return () => { + if (!ngUpgrade.$injector) { + throw new Error(` + RouterUpgradeInitializer can be used only after UpgradeModule.bootstrap has been called. + Remove RouterUpgradeInitializer and call setUpLocationSync after UpgradeModule.bootstrap. + `); + } + const router = ngUpgrade.injector.get(Router); const ref = ngUpgrade.injector.get(ApplicationRef); @@ -52,17 +62,28 @@ export function initialRouterNavigation( if (opts.initialNavigation === false) { router.setUpLocationChangeListener(); } else { - setTimeout(() => { router.initialNavigation(); }, 0); + router.initialNavigation(); } - // History.pushState does not fire onPopState, so the angular2 location - // doesn't detect it. The workaround is to attach a location change listener - // that will call navigate directly. - ngUpgrade.$injector.get('$rootScope') - .$on('$locationChangeStart', (_: any, next: string, __: string) => { - const url = document.createElement('a'); - url.href = next; - router.navigateByUrl(url.pathname); - }); + setUpLocationSync(ngUpgrade); }; +} + +/** + * @whatItDoes Sets up a location synchronization. + * + * History.pushState does not fire onPopState, so the angular2 location + * doesn't detect it. The workaround is to attach a location change listener + * + * @experimental + */ +export function setUpLocationSync(ngUpgrade: UpgradeModule): void { + const router: Router = ngUpgrade.injector.get(Router); + const url = document.createElement('a'); + + ngUpgrade.$injector.get('$rootScope') + .$on('$locationChangeStart', (_: any, next: string, __: string) => { + url.href = next; + router.navigateByUrl(url.pathname); + }); } \ No newline at end of file