Skip to content
This repository has been archived by the owner on Nov 16, 2021. It is now read-only.

Should support being provided with a SVG as a string #75

Open
espeandr opened this issue May 18, 2018 · 10 comments
Open

Should support being provided with a SVG as a string #75

espeandr opened this issue May 18, 2018 · 10 comments

Comments

@espeandr
Copy link

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.

@zygimantas
Copy link

Maybe proving an svg like this would keep the API clean:

[inlineSVG]="data:image/svg+xml,[...]"

@arkon
Copy link
Owner

arkon commented May 20, 2018

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.

@espeandr
Copy link
Author

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

@arkon
Copy link
Owner

arkon commented May 20, 2018

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?

@espeandr
Copy link
Author

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.

@arkon
Copy link
Owner

arkon commented May 21, 2018

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.

@andreclinio
Copy link

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!

@juliusstoerrle
Copy link

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.

@NiklasPor
Copy link

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 ?

@mcarriere
Copy link

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants