Skip to content

Commit c94828a

Browse files
author
Javier Cebrian
committed
Added fallback icon in case of broken link
1 parent d2d6acb commit c94828a

File tree

1 file changed

+47
-39
lines changed

1 file changed

+47
-39
lines changed

lib/svg-icon-registry.service.ts

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Injectable, Optional, SkipSelf } from '@angular/core';
1+
2+
import { Inject, Injectable, Optional, SkipSelf } from '@angular/core';
23
import { HttpClient } from '@angular/common/http';
34

45
import { Observable } from 'rxjs/Observable';
@@ -8,57 +9,64 @@ import 'rxjs/add/operator/do';
89
import 'rxjs/add/operator/finally';
910
import 'rxjs/add/operator/map';
1011
import 'rxjs/add/operator/share';
12+
import 'rxjs/observable/throw';
1113

1214

1315
@Injectable()
1416
export class SvgIconRegistryService {
1517

16-
private iconsByUrl = new Map<string, SVGElement>();
17-
private iconsLoadingByUrl = new Map<string, Observable<SVGElement>>();
18-
19-
constructor(private http:HttpClient) {
20-
}
18+
private iconsByUrl = new Map<string, SVGElement>();
19+
private iconsLoadingByUrl = new Map<string, Observable<SVGElement>>();
2120

22-
loadSvg(url:string): Observable<SVGElement> {
21+
constructor(private http: HttpClient, private fallbackIconUrl: string) {
22+
}
2323

24-
if (this.iconsByUrl.has(url)) {
25-
return Observable.of(this.iconsByUrl.get(url));
26-
} else if (this.iconsLoadingByUrl.has(url)) {
27-
return this.iconsLoadingByUrl.get(url);
28-
} else {
29-
const o = <Observable<SVGElement>> this.http.get(url, { responseType: 'text' })
30-
.map(svg => {
31-
const div = document.createElement('DIV');
32-
div.innerHTML = svg;
33-
return <SVGElement>div.querySelector('svg');
34-
})
35-
.do(svg => {
36-
this.iconsByUrl.set(url, svg);
37-
})
38-
.finally(() => {
39-
this.iconsLoadingByUrl.delete(url);
40-
})
41-
.share();
24+
loadSvg(url: string): Observable<SVGElement> {
25+
if (this.iconsByUrl.has(url)) {
26+
return Observable.of(this.iconsByUrl.get(url));
27+
} else if (this.iconsLoadingByUrl.has(url)) {
28+
return this.iconsLoadingByUrl.get(url);
29+
} else {
30+
const o = this.http.get(url, {responseType: 'text'})
31+
.map(svg => {
32+
const div = document.createElement('DIV');
33+
div.innerHTML = svg;
34+
return <SVGElement>div.querySelector('svg');
35+
})
36+
.catch((error) => {
37+
if (this.fallbackIconUrl) {
38+
return this.loadSvg(this.fallbackIconUrl);
39+
} else {
40+
return Observable.throw(error);
41+
}
42+
})
43+
.do(svg => {
44+
this.iconsByUrl.set(url, svg);
45+
})
46+
.finally(() => {
47+
this.iconsLoadingByUrl.delete(url);
48+
})
49+
.share();
50+
this.iconsLoadingByUrl.set(url, o);
51+
return o;
52+
}
4253

43-
this.iconsLoadingByUrl.set(url, o);
44-
return o;
45-
}
46-
}
54+
}
4755

48-
unloadSvg(url:string) {
49-
if (this.iconsByUrl.has(url)) {
50-
this.iconsByUrl.delete(url);
51-
}
52-
}
56+
unloadSvg(url: string) {
57+
if (this.iconsByUrl.has(url)) {
58+
this.iconsByUrl.delete(url);
59+
}
60+
}
5361

5462
}
5563

56-
export function SVG_ICON_REGISTRY_PROVIDER_FACTORY(parentRegistry:SvgIconRegistryService, http:HttpClient) {
57-
return parentRegistry || new SvgIconRegistryService(http);
64+
export function SVG_ICON_REGISTRY_PROVIDER_FACTORY(parentRegistry: SvgIconRegistryService, http: HttpClient, fallBackIconUrl: string) {
65+
return parentRegistry || new SvgIconRegistryService(http, fallBackIconUrl);
5866
}
5967

6068
export const SVG_ICON_REGISTRY_PROVIDER = {
61-
provide: SvgIconRegistryService,
62-
deps: [ [new Optional(), new SkipSelf(), SvgIconRegistryService], HttpClient ],
63-
useFactory: SVG_ICON_REGISTRY_PROVIDER_FACTORY
69+
provide: SvgIconRegistryService,
70+
deps: [[new Optional(), new SkipSelf(), SvgIconRegistryService], HttpClient, [new Inject('FALLBACK_ICON')]],
71+
useFactory: SVG_ICON_REGISTRY_PROVIDER_FACTORY,
6472
};

0 commit comments

Comments
 (0)