From fe962f6de7d65fa6fc62c6b22c9de3a60dfb7358 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Sun, 5 Mar 2017 15:33:51 +0000 Subject: [PATCH] fix(aio): LocationService urls should never start with a slash There is a weirdness in the Angular Location service. If the `baseHref` is only a single slash (`'/'`) then it changes it to be an empty string (`''`). The effect of this is that `Location.normaliseUrl(url)` does not strip off the leading slash from url paths. The problem is that the leading slash only appears on the initial Location path, and not on urls that arrive from subscribing to the Location service. This commit is a workaround this problem. --- aio/src/app/documents/document.service.ts | 2 +- aio/src/app/shared/location.service.spec.ts | 22 ++++++++++----------- aio/src/app/shared/location.service.ts | 15 +++++++++++--- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/aio/src/app/documents/document.service.ts b/aio/src/app/documents/document.service.ts index fb12bfc157..bbc68ea013 100644 --- a/aio/src/app/documents/document.service.ts +++ b/aio/src/app/documents/document.service.ts @@ -61,7 +61,7 @@ export class DocumentService { } private computePath(url) { - url = url.startsWith('/') ? url : '/' + url; + url = '/' + url; url = url.endsWith('/') ? url + 'index' : url; return 'content/docs' + url + '.json'; } diff --git a/aio/src/app/shared/location.service.spec.ts b/aio/src/app/shared/location.service.spec.ts index 71b209f3f6..7c589348bb 100644 --- a/aio/src/app/shared/location.service.spec.ts +++ b/aio/src/app/shared/location.service.spec.ts @@ -32,7 +32,7 @@ describe('LocationService', () => { let initialUrl; service.currentUrl.subscribe(url => initialUrl = url); - expect(initialUrl).toEqual('/next-url3'); + expect(initialUrl).toEqual('next-url3'); }); it('should emit all location changes after it has been subscribed to', () => { @@ -51,10 +51,10 @@ describe('LocationService', () => { location.simulatePopState('/next-url3'); expect(urls).toEqual([ - '/initial-url3', - '/next-url1', - '/next-url2', - '/next-url3' + 'initial-url3', + 'next-url1', + 'next-url2', + 'next-url3' ]); }); @@ -78,15 +78,15 @@ describe('LocationService', () => { location.simulatePopState('/next-url3'); expect(urls1).toEqual([ - '/initial-url3', - '/next-url1', - '/next-url2', - '/next-url3' + 'initial-url3', + 'next-url1', + 'next-url2', + 'next-url3' ]); expect(urls2).toEqual([ - '/next-url2', - '/next-url3' + 'next-url2', + 'next-url3' ]); }); }); diff --git a/aio/src/app/shared/location.service.ts b/aio/src/app/shared/location.service.ts index bc27aee3e8..155ffc81e6 100644 --- a/aio/src/app/shared/location.service.ts +++ b/aio/src/app/shared/location.service.ts @@ -10,13 +10,22 @@ export class LocationService { get currentUrl() { return this.urlSubject.asObservable(); } constructor(private location: Location) { - this.urlSubject = new BehaviorSubject(location.path(true)); - this.location.subscribe(state => this.urlSubject.next(state.url)); + + const initialUrl = this.stripLeadingSlashes(location.path(true)); + this.urlSubject = new BehaviorSubject(initialUrl); + + this.location.subscribe(state => { + const url = this.stripLeadingSlashes(state.url); + return this.urlSubject.next(url); + }); } go(url: string) { - url = this.location.normalize(url); this.location.go(url); this.urlSubject.next(url); } + + private stripLeadingSlashes(url: string) { + return url.replace(/^\/+/, ''); + } }