javascriptangularexternal-script

Angular 6 - Adding script at component level and checking if it exists


I have a script that I would like to run on one component only. I have managed to achieve adding the script on the component but a couple of things happen that I'm not entirely sure how to resolve.

  1. If I navigate to the component, the script is added to the DOM, but it isn't firing. If I refresh the page, it works
  2. If I navigate away to another component and return, the script is added again, and it can keep building up

component.ts

import { Component, OnInit } from '@angular/core';
import { Renderer2, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';

@Component({
  selector: 'app-privacy',
  templateUrl: './privacy.component.html',
  styles: []
})
export class PrivacyComponent implements OnInit {

  constructor(private _renderer2: Renderer2, @Inject(DOCUMENT) private _document) {
    let s = this._renderer2.createElement('script');
    s.type = `text/javascript`;
    s.src = `../../assets/scripts/privacy.js`;

    this._renderer2.appendChild(this._document.body, s);
   }

  ngOnInit() {
  }

}

Solution

  • You need to add the onload (if you need to support IE make sure to also support onreadystatechange) handler to your script element which can call a function you want to execute when the script is finished loading.

    To remove the script onNgDestroy, save a reference of createElement? on the Component and remove this in Destroy lifecycle hook.

    import { Component, OnInit, OnDestroy } from '@angular/core';
    import { Renderer2, Inject } from '@angular/core';
    import { DOCUMENT } from '@angular/platform-browser';
    
    @Component({
      selector: 'app-privacy',
      templateUrl: './privacy.component.html',
      styles: []
    })
    export class PrivacyComponent implements OnInit, OnDestroy {
      private s: any;
      constructor(private _renderer2: Renderer2, @Inject(DOCUMENT) private _document) {
        this.s = this._renderer2.createElement('script');
        this.s.type = `text/javascript`;
        this.s.src = `../../assets/scripts/privacy.js`;
        this.s.onload = this.doneLoading;
    
        this._renderer2.appendChild(this._document.body, this.s);
      }
    
      doneLoading () {
        // do what you need to do
      }
    
    
      ngOnDestroy() {
        // this removes the script so it won't be added again when the component gets initialized again.
        this._renderer2.removeChild(this._document.body, this.s)
      }
    
      ngOnInit() {
      }
    
    }