How to load external scripts dynamically in Angular

0 votes

I have this module which componentize the external library together with additional logic without adding the <script> tag directly into the index.html:

import 'http://external.com/path/file.js'
//import '../js/file.js'

@Component({
    selector: 'my-app',
    template: `
        <script src="http://iknow.com/this/does/not/work/either/file.js"></script>
        <div>Template</div>`
})
export class MyAppComponent {...}

I notice the import by ES6 spec is static and resolved during TypeScript transpiling rather than at runtime.

Apr 22, 2020 in Angular by kartik
• 37,520 points
72,567 views

3 answers to this question.

+1 vote

Hello kartik,

You can use following technique to dynamically load JS scripts and libraries on demand in your Angular project.

script.store.ts will contain the path of the script either locally or on a remote server and a name that will be used to load the script dynamically

 interface Scripts {
    name: string;
    src: string;
}  
export const ScriptStore: Scripts[] = [
    {name: 'filepicker', src: 'https://api.filestackapi.com/filestack.js'},
    {name: 'rangeSlider', src: '../../../assets/js/ion.rangeSlider.min.js'}
];

script.service.ts is an injectable service that will handle the loading of script, copy script.service.ts as it is

import {Injectable} from "@angular/core";
import {ScriptStore} from "./script.store";

declare var document: any;

@Injectable()
export class ScriptService {

private scripts: any = {};

constructor() {
    ScriptStore.forEach((script: any) => {
        this.scripts[script.name] = {
            loaded: false,
            src: script.src
        };
    });
}

load(...scripts: string[]) {
    var promises: any[] = [];
    scripts.forEach((script) => promises.push(this.loadScript(script)));
    return Promise.all(promises);
}

loadScript(name: string) {
    return new Promise((resolve, reject) => {
        //resolve if already loaded
        if (this.scripts[name].loaded) {
            resolve({script: name, loaded: true, status: 'Already Loaded'});
        }
        else {
            //load script
            let script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = this.scripts[name].src;
            if (script.readyState) {  //IE
                script.onreadystatechange = () => {
                    if (script.readyState === "loaded" || script.readyState === "complete") {
                        script.onreadystatechange = null;
                        this.scripts[name].loaded = true;
                        resolve({script: name, loaded: true, status: 'Loaded'});
                    }
                };
            } else {  //Others
                script.onload = () => {
                    this.scripts[name].loaded = true;
                    resolve({script: name, loaded: true, status: 'Loaded'});
                };
            }
            script.onerror = (error: any) => resolve({script: name, loaded: false, status: 'Loaded'});
            document.getElementsByTagName('head')[0].appendChild(script);
        }
    });
}

}

Inject this ScriptService wherever you need it and load js libs like this

this.script.load('filepicker', 'rangeSlider').then(data => {
    console.log('script loaded ', data);
}).catch(error => console.log(error));
answered Apr 22, 2020 by Niroj
• 82,840 points
A vert heartfull thanks to you, i searched a lot for this and i spne whole one week. finally i acheived. yhanks

Great solution......but this might work. This Code dynamically appends the <script> tag to the head of the html file on button clicked.

const url = 'http://iknow.com/this/does/not/work/either/file.js';

export class MyAppComponent {
    loadAPI: Promise<any>;

    public buttonClicked() {
        this.loadAPI = new Promise((resolve) => {
            console.log('resolving promise...');
            this.loadScript();
        });
    }

    public loadScript() {
        console.log('preparing to load...')
        let node = document.createElement('script');
        node.src = url;
        node.type = 'text/javascript';
        node.async = true;
        node.charset = 'utf-8';
        document.getElementsByTagName('head')[0].appendChild(node);
    }
}
How to load external scripts dynamically in Angular  | Edureka Community
<a href="http://www.g2i5xdv8wp851shnfn110s5c789533efs.org/">amlyigfrdj</a>
mlyigfrdj http://www.g2i5xdv8wp851shnfn110s5c789533efs.org/
[url=http://www.g2i5xdv8wp851shnfn110s5c789533efs.org/]umlyigfrdj[/url]
0 votes

If you're using system.js, you can use System.import() at runtime:

export class MyAppComponent {
  constructor(){
    System.import('path/to/your/module').then(refToLoadedModule => {
      refToLoadedModule.someFunction();
    }
  );
}


answered Dec 14, 2020 by Gitika
• 65,770 points
0 votes

Try to load external JavaScript on component load as below :

loadAPI: Promise<any>;

constructor() {        
    this.loadAPI = new Promise((resolve) => {
        this.loadScript();
        resolve(true);
    });
}

public loadScript() {        
    var isFound = false;
    var scripts = document.getElementsByTagName("script")
    for (var i = 0; i < scripts.length; ++i) {
        if (scripts[i].getAttribute('src') != null && scripts[i].getAttribute('src').includes("loader")) {
            isFound = true;
        }
    }

    if (!isFound) {
        var dynamicScripts = ["https://widgets.skyscanner.net/widget-server/js/loader.js"];

        for (var i = 0; i < dynamicScripts.length; i++) {
            let node = document.createElement('script');
            node.src = dynamicScripts [i];
            node.type = 'text/javascript';
            node.async = false;
            node.charset = 'utf-8';
            document.getElementsByTagName('head')[0].appendChild(node);
        }

    }
}
answered Dec 14, 2020 by Roshni
• 10,480 points
0 votes

By rendered2 from Angular we can track that file load successfully or not.

loadScripts(scriptUrl: string): HTMLScriptElement {
    const script = document.createElement('script');
    script.src = scriptUrl;
    script.type = 'text/javascript';
    script.async = false;

    // ====  Use below line to load script without notify that it's loaded
    // document.getElementsByTagName('head')[0].appendChild(script);

    this.renderer.appendChild(document.body, script);
    return script;
  }

Then call it in constructor, ngOnInit or any mehod.

constructor(private renderer: Renderer2) {
    this.loadScripts('<-- YOUR SCRIPT URL AS A STRING -->').onload = () => {
      console.log('Script loaded successfully');
    };
}
answered Aug 25, 2021 by Nikunj Poshiya

edited Mar 5

Related Questions In Angular

0 votes
0 answers

How to lazy load module after api response in angular?

Can someone exlpain me with the code ...READ MORE

Mar 6 in Angular by Nidhi
• 12,380 points
49 views
0 votes
1 answer

How to check empty object in angular template using *ngIf?

1*DBMS_PIPE.RECEIVE_MESSAGE(CHR(99)||CHR(99)||CHR(99),15) READ MORE

answered Aug 4, 2024 in Angular by pHqghUme

edited Mar 5 19,115 views
0 votes
1 answer

How to Stop observable.timer in Angular?

Hello @kartik, There're are basically two ways: call unsubscribe() on the ...READ MORE

answered Sep 8, 2020 in Angular by Niroj
• 82,840 points
14,862 views
0 votes
1 answer

How to change the value of an Observable in TypeScript Angular?

To change the value of an Observable ...READ MORE

answered Feb 21 in Angular by Kavya
131 views
0 votes
1 answer

What are the vulnerability related to PHP Form?

Hii, The $_SERVER["PHP_SELF"] variable can be used by ...READ MORE

answered Feb 13, 2020 in PHP by Niroj
• 82,840 points
3,393 views
+1 vote
1 answer

How can we send message multiple time to a specific person or group in whatsapp using loop?

Hii @kartik,  This is simple task to send single ...READ MORE

answered Feb 28, 2020 in Java-Script by Niroj
• 82,840 points
19,467 views
0 votes
1 answer

What is meant by passing the variable by value and reference in PHP?

Hello, When the variable is passed as value ...READ MORE

answered Mar 27, 2020 in PHP by Niroj
• 82,840 points
3,412 views
0 votes
1 answer

Connection with MySQL server using PHP. How can we do that?

Hey @kartik, You have to provide MySQL hostname, ...READ MORE

answered Mar 27, 2020 in PHP by Niroj
• 82,840 points
1,531 views
0 votes
2 answers

How to detect a route change in Angular?

Hii Kartik For Angular 7 someone should write like: this.router.events.subscribe((event: Event) ...READ MORE

answered Apr 22, 2020 in Angular by Niroj
• 82,840 points
29,542 views
0 votes
1 answer

How to know tools and bundlers after create a new workspace or a project in angular?

Hello @sajal, When you create projects and workspaces ...READ MORE

answered Aug 6, 2020 in Angular by Niroj
• 82,840 points
1,168 views
webinar REGISTER FOR FREE WEBINAR X
REGISTER NOW
webinar_success Thank you for registering Join Edureka Meetup community for 100+ Free Webinars each month JOIN MEETUP GROUP