Skip to content

Commit

Permalink
Added fallback icon in case of broken link
Browse files Browse the repository at this point in the history
  • Loading branch information
Javier Cebrian committed Apr 4, 2018
1 parent d2d6acb commit 3646dc5
Showing 1 changed file with 47 additions and 41 deletions.
88 changes: 47 additions & 41 deletions lib/svg-icon-registry.service.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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<string, SVGElement>();
private iconsLoadingByUrl = new Map<string, Observable<SVGElement>>();

constructor(private http:HttpClient) {
}
private iconsByUrl = new Map<string, SVGElement>();
private iconsLoadingByUrl = new Map<string, Observable<SVGElement>>();

loadSvg(url:string): Observable<SVGElement> {
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 = <Observable<SVGElement>> this.http.get(url, { responseType: 'text' })
.map(svg => {
const div = document.createElement('DIV');
div.innerHTML = svg;
return <SVGElement>div.querySelector('svg');
})
.do(svg => {
this.iconsByUrl.set(url, svg);
})
.finally(() => {
this.iconsLoadingByUrl.delete(url);
})
.share();
loadSvg(url: string): Observable<SVGElement> {
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 <SVGElement>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,
};

0 comments on commit 3646dc5

Please sign in to comment.