Skip to content

Commit 4aed4fb

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

File tree

1 file changed

+46
-41
lines changed

1 file changed

+46
-41
lines changed

lib/svg-icon-registry.service.ts

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Injectable, Optional, SkipSelf } from '@angular/core';
1+
import { Inject, Injectable, Optional, SkipSelf } from '@angular/core';
22
import { HttpClient } from '@angular/common/http';
33

44
import { Observable } from 'rxjs/Observable';
@@ -8,57 +8,62 @@ import 'rxjs/add/operator/do';
88
import 'rxjs/add/operator/finally';
99
import 'rxjs/add/operator/map';
1010
import 'rxjs/add/operator/share';
11+
import 'rxjs/observable/throw';
1112

12-
13-
@Injectable()
1413
export class SvgIconRegistryService {
1514

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

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

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

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

48-
unloadSvg(url:string) {
49-
if (this.iconsByUrl.has(url)) {
50-
this.iconsByUrl.delete(url);
51-
}
52-
}
53+
unloadSvg(url: string) {
54+
if (this.iconsByUrl.has(url)) {
55+
this.iconsByUrl.delete(url);
56+
}
57+
}
5358

5459
}
5560

56-
export function SVG_ICON_REGISTRY_PROVIDER_FACTORY(parentRegistry:SvgIconRegistryService, http:HttpClient) {
57-
return parentRegistry || new SvgIconRegistryService(http);
61+
export function SVG_ICON_REGISTRY_PROVIDER_FACTORY(parentRegistry: SvgIconRegistryService, http: HttpClient, fallBackIconUrl: string) {
62+
return parentRegistry || new SvgIconRegistryService(http, fallBackIconUrl);
5863
}
5964

6065
export const SVG_ICON_REGISTRY_PROVIDER = {
61-
provide: SvgIconRegistryService,
62-
deps: [ [new Optional(), new SkipSelf(), SvgIconRegistryService], HttpClient ],
63-
useFactory: SVG_ICON_REGISTRY_PROVIDER_FACTORY
66+
provide: SvgIconRegistryService,
67+
deps: [[new Optional(), new SkipSelf(), SvgIconRegistryService], HttpClient, [new Inject('FALLBACK_ICON')]],
68+
useFactory: SVG_ICON_REGISTRY_PROVIDER_FACTORY,
6469
};

0 commit comments

Comments
 (0)