ng-inline-svg
ng-inline-svg copied to clipboard
Should support being provided with a SVG as a string
I'm submitting a...
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[x] Feature request
[ ] Documentation issue or request
Current behavior
Currently the directive only support beeing provided a SVG through a URL.
Wanted behaviour
I would like to be able to pass the directive a SVG as a string, like so:
@Component({
selector: 'demo',
template: `
<div [inlineSVG]="svgAsString" [isSVGString]="true"></div>
`
})
export class DemoComponent {
public svgAsString = `
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<circle cx="5.899" cy="8.979" r="2.792"/>
</svg>`;
}
What is the motivation / use case for changing the behavior?
By beeing able to provide SVG as a string, developers can handle the fetching of the SVG themselves. My concrete need is to be able to implement a retry mechanism on the fetching of the SVG.
Maybe proving an svg like this would keep the API clean:
[inlineSVG]="data:image/svg+xml,[...]"
I'm not sure if it's really practical as a library user to provide data URIs. That said, I'm not entirely sure why you would readily have an SVG as a string either. It'd make more sense to me if you had the element itself, but @espeandr can chime in.
I did express the motivation behind this issue in the original issue's body, but I'll try to rephrase:
This directive handles fetching of a SVG by using the HttpClient
in the SVGCacheService,
based on a URL a user provides like so: this._http.get(absUrl, {responseType: 'text'})
. The response of such a request would be a SVG as a string. I would like to handle this fetching myself, so that I can implement a mechanism that in cases of error responses retries the GET-request until a valid response is achieved, e.g. by using the rxjs retryWhen
operator. When I have the response, I can then provide this string to this directive. I think this makes this directive more flexible by giving users an option of handling querying for the SVG themselves, not relying on the mechanics as implemented in SVGCacheService
If that's the case, wouldn't it make more sense to be able to specify something to use for fetching the SVG, which the directive can use in place of the default SVGCacheService
?
I see your point, but wouldn't this service that replaces SVGCacheService
also have to implement SVGCacheService
's setBaseUrl
and getAbsoluteUrl
, unless more substantial refactoring is done? Another solution could be to provide a class that replaces SVGCacheService
use of the HttpClient
during registration of the module.
In my case, such a class would retry failing requests, as well as alerting users that a issue has occurred by displaying a toast through another dependent service. However, I might not want this "retry and alert" mechanism for all SVGs I insert using this directive. To solve this, one could provide the directive with such a service as a input instead, or have a flag deciding whether to use the default "SVGFetcher (HttpClient
) or a custom service that was provided during module registration. I think this is feasible, but I also think it would complicate the API quite a bit. Also, I'm not really sure coupling services for fetching, retrying and alerting into this directive for inlining SVGs is the cleanest approach either.
I might have misunderstood your suggestion, or there might be a better way to do what you suggested @arkon, but based on what I laid out above, I still think allowing users to provide the directive with a SVG as a string directly is the simplest and most flexible way to give consumers of the directive control of the fetching of a SVG themselves.
From my implementation point of view, it'd just be a matter of providing the user a way of passing in an implementer of a SVGFetcher
interface, which has a single function: getSVG(id: string): Observable<SVGElement>
. SVGCacheService
would be the default implementation, where it handles id
being a relative or absolute URL.
Maybe it'd be possible to provide both the current SVGCacheService
and another one that handles an SVG as a string as well.
I have a case where the svg definition is inside a database (CLOB). I would simply take this string and render it inside my component (caches are working fine). It would be a nice feature!
In my case this is usefull because I need to load a few hundred svgs and doing a single HTTP Request for them is not really nice. Fetching them all at the same time in a json document would be much nicer.
I'm currently really struggling with finding a good svg injector, which supports an svg string. Is there currently a workaround for using a string based svg resource with inlineSVG
?
It is also something I would find useful as i'm storing some SVGs inside indexedDB for offline use. The SVGFetcher implementation would be inconvenient in my case because I have more than one type of svg and they come from different sources.