google-mapsgoogle-apps-scriptdynamic-import

Dynamic Library Import for Maps JavaScript API not working in Apps script


I'm trying to switch to the Dynamic Library Import API (from the outdated script tag). I made an example according to the documentation in a Google spreadsheet on Apps Script. As a result, I expect to get a Google map in the browser, but I get an error in the console

userCodeAppPanel:2 Uncaught SyntaxError: Unexpected end of input userCodeAppPanel:6 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'importLibrary') at initMap (userCodeAppPanel:6:39) at userCodeAppPanel:15:1

Below is the code from Apps script:

<!doctype html>
<html>
  <head>
    <title>Simple Map</title>
    <script>
let map; 
// initMap is now async
async function initMap() { 
    // Request libraries when needed, not in the script tag.
    const { Map } = await google.maps.importLibrary("maps");
    // Short namespaces can be used.
    map = new Map(document.getElementById("map"), {
        center: { lat: 40.72476, lng: -74.04843 },
        zoom: 8,
    });

}

initMap();
</script>
  </head>
  <body>
    <div id="map"></div>
  
   <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src="https://maps.${c}apis.com/maps/api/js?"+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "weekly"});</script>

<style>
#map {
  height: 100%;
}

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
  background-color: grey;
}
</style>
  </body>
</html>

But the same code in jsfiddle is processed without errors (the result is displayed as a map).

I assume that something is missing in Apps Script. Please help me understand the reason and run the code on Dynamic Library Import

Update: Fixing the quotes partially solved the problem (Thanks Tanaike). Now the error remains:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'importLibrary')

To reproduce the error, you can use a Google spreadsheet with a modal window call. First, press F12 to display the console in the browser, then the script button and open the map


Solution

  • When I saw your showing script, I remembered this issue. https://issuetracker.google.com/issues/156139610 In the current stage, when Javascript is written in an HTML file with the script editor of Google Apps Script, when // is included in the template literal, it seems that this line is used as a comment line. In your script, at a.src=`https://maps.${c}apis.com/maps/api/js?`+e, // is used. By this, the script after // is used as a comment. I guessed that this issue might be the reason for your current issue.

    In order to remove this issue, please modify it as follows.

    From:

    a.src=`https://maps.${c}apis.com/maps/api/js?`+e
    

    To:

    a.src=`https:\/\/maps.${c}apis.com/maps/api/js?`+e
    

    When you modify the script of Web Apps, please reflect the latest script to Web Apps. Please be careful about this.

    Note:

    Reference:

    Added:

    How about the following modification?

    <!doctype html>
    <html>
    
    <head>
      <title>Simple Map</title>
      <style>
        #map {
          height: 100%;
        }
    
        html,
        body {
          height: 100%;
          margin: 0;
          padding: 0;
          background-color: grey;
        }
      </style>
    
      <script>
      (g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https:\/\/maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })
        ({ key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "weekly" });
      </script>
    
      <script>
      let map;
      console.log('let map');
    
      async function initMap() {
        console.log('start initMap');
        // Request libraries when needed, not in the script tag.
        const { Map } = await google.maps.importLibrary("maps");
        // Short namespaces can be used.
    
        map = new Map(document.getElementById("map"), {
          center: { lat: 50.397, lng: -70.644 },
          zoom: 4
        });
      }
    
      initMap();
      </script>
    </head>
    
    <body>
      <div id="map"></div>
    </body>
    
    </html>