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:
parent
04e14589c4
commit
fe962f6de7
|
@ -61,7 +61,7 @@ export class DocumentService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private computePath(url) {
|
private computePath(url) {
|
||||||
url = url.startsWith('/') ? url : '/' + url;
|
url = '/' + url;
|
||||||
url = url.endsWith('/') ? url + 'index' : url;
|
url = url.endsWith('/') ? url + 'index' : url;
|
||||||
return 'content/docs' + url + '.json';
|
return 'content/docs' + url + '.json';
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ describe('LocationService', () => {
|
||||||
|
|
||||||
let initialUrl;
|
let initialUrl;
|
||||||
service.currentUrl.subscribe(url => initialUrl = url);
|
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', () => {
|
it('should emit all location changes after it has been subscribed to', () => {
|
||||||
|
@ -51,10 +51,10 @@ describe('LocationService', () => {
|
||||||
location.simulatePopState('/next-url3');
|
location.simulatePopState('/next-url3');
|
||||||
|
|
||||||
expect(urls).toEqual([
|
expect(urls).toEqual([
|
||||||
'/initial-url3',
|
'initial-url3',
|
||||||
'/next-url1',
|
'next-url1',
|
||||||
'/next-url2',
|
'next-url2',
|
||||||
'/next-url3'
|
'next-url3'
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -78,15 +78,15 @@ describe('LocationService', () => {
|
||||||
location.simulatePopState('/next-url3');
|
location.simulatePopState('/next-url3');
|
||||||
|
|
||||||
expect(urls1).toEqual([
|
expect(urls1).toEqual([
|
||||||
'/initial-url3',
|
'initial-url3',
|
||||||
'/next-url1',
|
'next-url1',
|
||||||
'/next-url2',
|
'next-url2',
|
||||||
'/next-url3'
|
'next-url3'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(urls2).toEqual([
|
expect(urls2).toEqual([
|
||||||
'/next-url2',
|
'next-url2',
|
||||||
'/next-url3'
|
'next-url3'
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,13 +10,22 @@ export class LocationService {
|
||||||
get currentUrl() { return this.urlSubject.asObservable(); }
|
get currentUrl() { return this.urlSubject.asObservable(); }
|
||||||
|
|
||||||
constructor(private location: Location) {
|
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) {
|
go(url: string) {
|
||||||
url = this.location.normalize(url);
|
|
||||||
this.location.go(url);
|
this.location.go(url);
|
||||||
this.urlSubject.next(url);
|
this.urlSubject.next(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private stripLeadingSlashes(url: string) {
|
||||||
|
return url.replace(/^\/+/, '');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue