Repository: googlemaps/js-api-loader
Pull request #60 (2020-09-30 22:09:45)

feat: allow setting script id

codecov[bot]: # [Codecov](https://codecov.io/gh/googlemaps/js-api-loader/pull/60?src=pr&el=h1) Report
> Merging [#60](https://codecov.io/gh/googlemaps/js-api-loader/pull/60?src=pr&el=desc) into [master](https://codecov.io/gh/googlemaps/js-api-loader/commit/1c41fad663a1c456494dc4a7dc46285b10a85d34?el=desc) will **not change** coverage.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/googlemaps/js-api-loader/pull/60/graphs/tree.svg?width=650&height=150&src=pr&token=aAmgcWFXMs)](https://codecov.io/gh/googlemaps/js-api-loader/pull/60?src=pr&el=tree)

```diff
@@            Coverage Diff            @@
##            master       #60   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            1         1           
  Lines           75        81    +6     
  Branches        11        13    +2     
=========================================
+ Hits            75        81    +6     
```


| [Impacted Files](https://codecov.io/gh/googlemaps/js-api-loader/pull/60?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/index.ts](https://codecov.io/gh/googlemaps/js-api-loader/pull/60/diff?src=pr&el=tree#diff-c3JjL2luZGV4LnRz) | `100.00% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/googlemaps/js-api-loader/pull/60?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/googlemaps/js-api-loader/pull/60?src=pr&el=footer). Last update [1c41fad...791df79](https://codecov.io/gh/googlemaps/js-api-loader/pull/60?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/src/index.ts b/src/index.ts
index 1fd7bf8..35ed926 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -23,7 +23,13 @@ declare global {
   }
 }
 
-type Libraries = ("drawing" | "geometry" | "localContext" | "places" | "visualization")[];
+type Libraries = (
+  | "drawing"
+  | "geometry"
+  | "localContext"
+  | "places"
+  | "visualization"
+)[];
 
 /**
  * The Google Maps JavaScript API
@@ -65,6 +71,10 @@ export interface LoaderOptions {
    * receive your default channel.
    */
   version?: string;
+  /**
+   * The id of the script tag. Before adding a new script, the Loader will check for an existing one.
+   */
+  id?: string;
   /**
    * When loading the Maps JavaScript API via the URL you may optionally load
    * additional libraries through use of the libraries URL parameter. Libraries
@@ -164,6 +174,10 @@ export class Loader {
    * See [[LoaderOptions.apiKey]]
    */
   apiKey: string;
+  /**
+   * See [[LoaderOptions.id]]
+   */
+  id: string;
   /**
    * See [[LoaderOptions.libraries]]
    */
@@ -205,6 +219,7 @@ export class Loader {
    */
   constructor({
     apiKey,
+    id = "__googleMapsScriptId",
     libraries = [],
     language,
     region,
@@ -214,6 +229,7 @@ export class Loader {
   }: LoaderOptions) {
     this.version = version;
     this.apiKey = apiKey;
+    this.id = id;
     this.libraries = libraries;
     this.language = language;
     this.region = region;
@@ -293,9 +309,14 @@ export class Loader {
    * Set the script on document.
    */
   private setScript(): void {
+    if (this.id && document.getElementById(this.id)) {
+      this.callback();
+      return;      
+    }
+    
     const url = this.createUrl();
     const script = document.createElement("script");
-
+    script.id = this.id;
     script.type = "text/javascript";
     script.src = url;
     script.onerror = this.loadErrorCallback.bind(this);


Test patch:
diff --git a/src/index.test.ts b/src/index.test.ts
index 9625398..727cff2 100644
--- a/src/index.test.ts
+++ b/src/index.test.ts
@@ -16,6 +16,10 @@
 
 import { Loader, LoaderOptions } from ".";
 
+afterEach(() => {
+  document.getElementsByTagName('html')[0].innerHTML = ''; 
+});
+
 test.each([
   [{}, "https://maps.googleapis.com/maps/api/js?callback=__googleMapsCallback"],
   [
@@ -52,6 +56,7 @@ test("setScript adds a script to head with correct attributes", () => {
 
   const script = document.head.childNodes[0] as HTMLScriptElement;
 
+  expect(script.id).toEqual(loader.id);
   expect(script.src).toEqual(loader.createUrl());
   expect(script.defer).toBeTruthy();
   expect(script.async).toBeTruthy();
@@ -59,6 +64,21 @@ test("setScript adds a script to head with correct attributes", () => {
   expect(script.type).toEqual("text/javascript");
 });
 
+test("setScript does not add second script with same id", () => {
+  new Loader({ apiKey: "foo", id: "bar" })['setScript']();
+  new Loader({ apiKey: "foo", id: "bar" })['setScript']();
+
+  expect(document.head.childNodes.length).toBe(1);
+});
+
+test("setScript adds a script with id", () => {
+  const loader = new Loader({ apiKey: "foo", id: "bar" });
+  loader["setScript"]();
+
+  const script = document.head.childNodes[0] as HTMLScriptElement;
+  expect(script.id).toEqual(loader.id);
+});
+
 test("load should return a promise that resolves even if called twice", () => {
   const loader = new Loader({ apiKey: "foo" });