Angular: Dynamically inserting SVG into an element

Published

I was recently asked to make a single-page web app for a digital illustrator. The app was pretty standard but they asked a unique request. The author did not want me to create renditions of their work in BPM, PNG, or JPEG formats. Instead, they wanted me to dynamically store and deliver SVG data from a database. Think, Base64 images but for vector-based artwork.

On the database side, it's nothing to complex. I chose Firebase as my real-time backend but the rest of this entry will show you a few different ways on how to render SVG using Angular.

SVG within Firebase


Getting Started

Here is an example of SVG content.

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 width="612px" height="502.174px" viewBox="0 65.326 612 502.174" enable-background="new 0 65.326 612 502.174"
	 xml:space="preserve">
<ellipse fill="#C6C6C6" cx="283.5" cy="487.5" rx="259" ry="80"/>
<path id="bird" d="M210.333,65.331C104.367,66.105-12.349,150.637,1.056,276.449c4.303,40.393,18.533,63.704,52.171,79.03
	c36.307,16.544,57.022,54.556,50.406,112.954c-9.935,4.88-17.405,11.031-19.132,20.015c7.531-0.17,14.943-0.312,22.59,4.341
	c20.333,12.375,31.296,27.363,42.979,51.72c1.714,3.572,8.192,2.849,8.312-3.078c0.17-8.467-1.856-17.454-5.226-26.933
	c-2.955-8.313,3.059-7.985,6.917-6.106c6.399,3.115,16.334,9.43,30.39,13.098c5.392,1.407,5.995-3.877,5.224-6.991
	c-1.864-7.522-11.009-10.862-24.519-19.229c-4.82-2.984-0.927-9.736,5.168-8.351l20.234,2.415c3.359,0.763,4.555-6.114,0.882-7.875
	c-14.198-6.804-28.897-10.098-53.864-7.799c-11.617-29.265-29.811-61.617-15.674-81.681c12.639-17.938,31.216-20.74,39.147,43.489
	c-5.002,3.107-11.215,5.031-11.332,13.024c7.201-2.845,11.207-1.399,14.791,0c17.912,6.998,35.462,21.826,52.982,37.309
	c3.739,3.303,8.413-1.718,6.991-6.034c-2.138-6.494-8.053-10.659-14.791-20.016c-3.239-4.495,5.03-7.045,10.886-6.876
	c13.849,0.396,22.886,8.268,35.177,11.218c4.483,1.076,9.741-1.964,6.917-6.917c-3.472-6.085-13.015-9.124-19.18-13.413
	c-4.357-3.029-3.025-7.132,2.697-6.602c3.905,0.361,8.478,2.271,13.908,1.767c9.946-0.925,7.717-7.169-0.883-9.566
	c-19.036-5.304-39.891-6.311-61.665-5.225c-43.837-8.358-31.554-84.887,0-90.363c29.571-5.132,62.966-13.339,99.928-32.156
	c32.668-5.429,64.835-12.446,92.939-33.85c48.106-14.469,111.903,16.113,204.241,149.695c3.926,5.681,15.819,9.94,9.524-6.351
	c-15.893-41.125-68.176-93.328-92.13-132.085c-24.581-39.774-14.34-61.243-39.957-91.247
	c-21.326-24.978-47.502-25.803-77.339-17.365c-23.461,6.634-39.234-7.117-52.98-31.273C318.42,87.525,265.838,64.927,210.333,65.331
	z M445.731,203.01c6.12,0,11.112,4.919,11.112,11.038c0,6.119-4.994,11.111-11.112,11.111s-11.038-4.994-11.038-11.111
	C434.693,207.929,439.613,203.01,445.731,203.01z"/>
</svg>

Method #1 - Angular Decorators

This method uses experimental support for decorators. The Angular Cli will tell you that it's experimental and may change.

angular-decorators

HTML

Place a div within your name.component.html.

<div #dataContainer></div>

Component

Place this within your name.component.ts.

import { Component, OnInit } from '@angular/core';
import { ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  @ViewChild('dataContainer') dataContainer: ElementRef;

  constructor() { }

  ngOnInit() {
       svg = "SVG CONTENT"
       this.dataContainer.nativeElement.innerHTML = svg;
    })
  }
}

Source


Method #2 - [innerHTML]

Place this within your name.component.ts.

<div class="svg" [innerHTML]="svg"></div>

Place this within your name.component.ts.

import { Component, OnInit } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  svg:SafeHtml;

  constructor(private sanitizer: DomSanitizer) { }

  ngOnInit() {
      this.svg = this.sanitizer.bypassSecurityTrustHtml("‹‹ SVG CONTENT ››");

    })
  }
}

Source


Method 3 - Use a Plugin

This method works best if you have a static SVG file that you want to dynamically load. The two methods above are ideal if you want to store the actual SVG data within a database.

Install ng-inline-svg.

npm install ng-inline-svg

Place this within your name.component.html.

<div [inlineSVG]="svg"></div>

Place this within your app.module.ts.

import { InlineSVGModule } from 'ng-inline-svg';
 
@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, InlineSVGModule],
  bootstrap: [AppComponent]
})
class AppModule {}

Source


Resources

Comments