Search code examples
google-maps-api-3javascript-objectssveltesveltekit

How can my google maps api iterate over an object in a different script?


When I put my object (points) in the same script as the google maps API it works fine. But when I move the object to its own script on top it says "points is not defined".

I need to have the object in the top script (its actually coming from a database).

See working demo: https://price-points.web.app/

This is a Svelte project.

<script>
  export const prerender = true;
  let showMap = false;
  //How can I make this work without the setTimeout?
  setTimeout(function(){showMap = !showMap}, 1); 
</script>

<!-- Google Maps API -->
<div> 
  <div id="map"></div>  
  <script>  
    //If points object is here it works fine.
    //If points is defined in top script it says "points is not defined"
    //My ACTUAL points object comes from a database and needs to be in top script.
    let points = {
      sanFrancisco: {
          lat: 37.7749,
          lng: -122.4194,
          price: 123.45
      },
      losAngeles: {
          lat: 34.0522,
          lng: -118.2437,
          price: 567.89
      }
    }
    function initMap() {    
      const california = {lat: 36.7783,lng: -119.4179};
      const map = new google.maps.Map(document.getElementById("map"), {
        zoom: 7,
        center: california,
      });
      Object.values(points).forEach(({ lat, lng, price }) => {
        const marker = new google.maps.Marker({
          position: {lat: lat, lng: lng},
          map: map,
          label: `$${price}`,
          icon: { url: 'https://i.imgur.com/ECXgKpB.png', scaledSize: new google.maps.Size(60,35), labelOrigin: new google.maps.Point(30, 15)}       
        });
      });
    }
    window.initMap = initMap;
  </script> 
  {#if showMap} 
  <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&v=weekly" defer async></script>
  {/if}
</div>

<style>
  #map {
  height: 800px;
  width: 100%;
  }
</style>

Solution

  • The script in Svelte components is scoped (it is implicitly a module which requires import/export), you have to set window.points to make variables available globally.

    Note that in SvelteKit you cannot access window during server-side rendering, so you probably should move the assignment into onMount. In general you should not have multiple script tags in the first place, maybe you are fighting the wrong problem.