Created
June 21, 2018 20:27
-
-
Save sebastiandg7/a670d614699912f55e4d3668dbe7604f to your computer and use it in GitHub Desktop.
Angular: dynamically load local or URL hosted JS scripts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Scripts { | |
name: string; | |
src: string; | |
} | |
export const GOOGLE_MAPS = 'GOOGLE_MAPS'; | |
export const RANGE_SLIDER = 'RANGE_SLIDER'; | |
export const ScriptStore: Scripts[] = [ | |
{name: GOOGLE_MAPS, src: 'https://maps.googleapis.com/maps/api/js?key=<api_token>'}, | |
{name: RANGE_SLIDER, src: '../../../assets/js/ion.rangeSlider.min.js'} | |
]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Usage example | |
// =========================================================== | |
// google-maps.service.ts | |
import { Injectable } from '@angular/core'; | |
import { ScriptService } from '../scripts/script.service'; | |
import { GOOGLE_MAPS } from '../scripts/script.store'; | |
@Injectable({ | |
providedIn: 'root' | |
}) | |
export class GoogleMapsService { | |
constructor(private scriptService: ScriptService) { } | |
init(): Promise<any[]> { | |
return this.scriptService.load(GOOGLE_MAPS); | |
} | |
} | |
// =========================================================== | |
// my-component.component.ts | |
import { Component, OnInit } from '@angular/core'; | |
import { GoogleMapsService } from '../../route/to/google-maps.service'; | |
@Component({ | |
selector: 'app-my-component', | |
templateUrl: './my-component.component.html', | |
styleUrls: ['./my-component.component.css'] | |
}) | |
export class MyComponent implements OnInit { | |
constructor(private googleMapsService: GoogleMapsService) { } | |
ngOnInit() { | |
this.googleMapsService.init().then(() => { | |
console.log(google.maps); | |
}); | |
} | |
} | |
// =========================================================== | |
// If typings are not defined for the library you must | |
// install them from @types/your-library (if exists) if not, | |
// you must define them in your typing.d.ts | |
declare namespace google { | |
export var maps: any; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Grabbed from: https://stackoverflow.com/a/42766146/5994580