diff --git a/lib/svg-icon-registry.service.ts b/lib/svg-icon-registry.service.ts index 76296e4..33ed99f 100644 --- a/lib/svg-icon-registry.service.ts +++ b/lib/svg-icon-registry.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Optional, SkipSelf } from '@angular/core'; +import { Inject, Injectable, Optional, SkipSelf } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; @@ -8,57 +8,63 @@ import 'rxjs/add/operator/do'; import 'rxjs/add/operator/finally'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/share'; +import 'rxjs/observable/throw'; +import 'rxjs/add/operator/catch'; - -@Injectable() export class SvgIconRegistryService { - private iconsByUrl = new Map(); - private iconsLoadingByUrl = new Map>(); - - constructor(private http:HttpClient) { - } + private iconsByUrl = new Map(); + private iconsLoadingByUrl = new Map>(); - loadSvg(url:string): Observable { + constructor(private http: HttpClient, private fallbackIconUrl: string) { + } - if (this.iconsByUrl.has(url)) { - return Observable.of(this.iconsByUrl.get(url)); - } else if (this.iconsLoadingByUrl.has(url)) { - return this.iconsLoadingByUrl.get(url); - } else { - const o = > this.http.get(url, { responseType: 'text' }) - .map(svg => { - const div = document.createElement('DIV'); - div.innerHTML = svg; - return div.querySelector('svg'); - }) - .do(svg => { - this.iconsByUrl.set(url, svg); - }) - .finally(() => { - this.iconsLoadingByUrl.delete(url); - }) - .share(); + loadSvg(url: string): Observable { + if (this.iconsByUrl.has(url)) { + return Observable.of(this.iconsByUrl.get(url)); + } else if (this.iconsLoadingByUrl.has(url)) { + return this.iconsLoadingByUrl.get(url); + } else { + const o = this.http.get(url, {responseType: 'text'}) + .map(svg => { + const div = document.createElement('DIV'); + div.innerHTML = svg; + return div.querySelector('svg'); + }) + .catch((error) => { + if (this.fallbackIconUrl) { + return this.loadSvg(this.fallbackIconUrl); + } else { + return Observable.throw(error); + } + }) + .do(svg => { + this.iconsByUrl.set(url, svg); + }) + .finally(() => { + this.iconsLoadingByUrl.delete(url); + }) + .share(); + this.iconsLoadingByUrl.set(url, o); + return o; + } - this.iconsLoadingByUrl.set(url, o); - return o; - } - } + } - unloadSvg(url:string) { - if (this.iconsByUrl.has(url)) { - this.iconsByUrl.delete(url); - } - } + unloadSvg(url: string) { + if (this.iconsByUrl.has(url)) { + this.iconsByUrl.delete(url); + } + } } -export function SVG_ICON_REGISTRY_PROVIDER_FACTORY(parentRegistry:SvgIconRegistryService, http:HttpClient) { - return parentRegistry || new SvgIconRegistryService(http); +export function SVG_ICON_REGISTRY_PROVIDER_FACTORY(parentRegistry: SvgIconRegistryService, http: HttpClient, fallBackIconUrl: string) { + return parentRegistry || new SvgIconRegistryService(http, fallBackIconUrl); } export const SVG_ICON_REGISTRY_PROVIDER = { - provide: SvgIconRegistryService, - deps: [ [new Optional(), new SkipSelf(), SvgIconRegistryService], HttpClient ], - useFactory: SVG_ICON_REGISTRY_PROVIDER_FACTORY + provide: SvgIconRegistryService, + deps: [[new Optional(), new SkipSelf(), SvgIconRegistryService], HttpClient, [new Inject('FALLBACK_ICON')]], + useFactory: SVG_ICON_REGISTRY_PROVIDER_FACTORY, };