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.
This commit is contained in:
Peter Bacon Darwin 2017-03-05 15:33:51 +00:00 committed by Igor Minar
parent 04e14589c4
commit fe962f6de7
3 changed files with 24 additions and 15 deletions

View File

@ -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';
}

View File

@ -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'
]);
});
});

View File

@ -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(/^\/+/, '');
}
}