Created
December 22, 2016 08:47
-
-
Save aegyed91/39e36e054af68aa563150d732101d607 to your computer and use it in GitHub Desktop.
script-loader
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
// credits: https://github.com/SebastianM/angular2-google-maps/blob/master/src/core/services/maps-api-loader/lazy-maps-api-loader.ts | |
import { Injectable } from '@angular/core'; | |
import { isEmpty } from 'lodash'; | |
let _callbacks = 0; | |
/** | |
* Configuration for the {@link ScriptLoader}. | |
*/ | |
export interface ScriptLoaderConfig { | |
/** | |
* The Google Maps API Key (see: | |
* https://developers.google.com/maps/documentation/javascript/get-api-key) | |
*/ | |
apiKey?: string; | |
/** | |
* The Google Maps client ID (for premium plans). | |
* When you have a Google Maps APIs Premium Plan license, you must authenticate | |
* your application with either an API key or a client ID. | |
* The Google Maps API will fail to load if both a client ID and an API key are included. | |
*/ | |
clientId?: string; | |
/** | |
* The Google Maps channel name (for premium plans). | |
* A channel parameter is an optional parameter that allows you to track usage under your client | |
* ID by assigning a distinct channel to each of your applications. | |
*/ | |
channel?: string; | |
/** | |
* Google Maps API version. | |
*/ | |
apiVersion?: string; | |
/** | |
* Host and Path used for the `<script>` tag. | |
*/ | |
hostAndPath?: string; | |
/** | |
* Protocol used for the `<script>` tag. | |
*/ | |
protocol?: string; | |
/** | |
* Defines which Google Maps libraries should get loaded. | |
*/ | |
libraries?: string[]; | |
/** | |
* The default bias for the map behavior is US. | |
* If you wish to alter your application to serve different map tiles or bias the | |
* application, you can overwrite the default behavior (US) by defining a `region`. | |
* See https://developers.google.com/maps/documentation/javascript/basics#Region | |
*/ | |
region?: string; | |
/** | |
* The Google Maps API uses the browser's preferred language when displaying | |
* textual information. If you wish to overwrite this behavior and force the API | |
* to use a given language, you can use this setting. | |
* See https://developers.google.com/maps/documentation/javascript/basics#Language | |
*/ | |
language?: string; | |
} | |
@Injectable() | |
export class ScriptLoaderS { | |
constructor() { | |
} | |
load(c: ScriptLoaderConfig): Promise<void> { | |
const promiseName = 'script_loader_promise_' + _callbacks; | |
// const callbackName = 'script_loader_cb_' + _callbacks; | |
if (this[promiseName]) { | |
return this[promiseName]; | |
} | |
const script = document.createElement('script'); | |
script.type = 'text/javascript'; | |
script.async = true; | |
script.defer = true; | |
script.src = this._getScriptSrc(c/*, callbackName*/); | |
this[promiseName] = new Promise((resolve, reject) => { | |
// window[callbackName] = () => { | |
// delete this[promiseName]; | |
// delete window[callbackName]; | |
// resolve(); | |
// }; | |
script.onload = () => { | |
delete this[promiseName]; | |
resolve(); | |
}; | |
script.onerror = error => { | |
reject(error); | |
}; | |
}); | |
document.body.appendChild(script); | |
_callbacks = _callbacks + 1; | |
return this[promiseName]; | |
} | |
private _getScriptSrc(c/*, callbackName*/) { | |
const protocol = c.protocol || 'https'; | |
const hostAndPath = c.hostAndPath; | |
const queryParams = { | |
v: c.apiVersion || '3', | |
// callback: callbackName, | |
key: c.apiKey, | |
client: c.clientId, | |
channel: c.channel, | |
libraries: c.libraries, | |
region: c.region, | |
language: c.language | |
}; | |
const params = Object.keys(queryParams) | |
.filter(k => !isEmpty(queryParams[k])) | |
.map(k => { | |
// join arrays as comma seperated strings | |
let i = queryParams[k]; | |
if (Array.isArray(i)) { | |
return {key: k, value: i.join(',')}; | |
} | |
return {key: k, value: queryParams[k]}; | |
}) | |
.map((entry: {key: string, value: string}) => { | |
return `${entry.key}=${entry.value}`; | |
}) | |
.join('&'); | |
return `${protocol}://${hostAndPath}?${params}`; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment