Search code examples
javascriptgoogle-mapsgoogle-maps-api-3

Reload Markers on Google's Maps API


Here is my code(most code from Google's API page).

<script>
    var beaches = [
      ['Bondi Beach', -12.890542, 120.274856, 4],
      ['Coogee Beach', -12.923036, 520.259052, 5],
      ['Cronulla Beach', -12.028249, 1221.157507, 3],
      ['Manly Beach', -12.80010128657071, 1121.28747820854187, 2],
      ['Maroubra Beach', -33.950198, 121.259302, 1]
    ];

    function setMarkers(map, locations) {
      for (var i = 0; i < locations.length; i++) {
        var beach = locations[i];
        var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
        var marker = new google.maps.Marker({
            position: myLatLng,
            map: map,
            title: beach[0],
            zIndex: beach[3]
        });
      }
    }

    function initialize() {
      var mapOptions = {
        zoom: 3,
        center: new google.maps.LatLng(38.77417, -9.13417),
        mapTypeId: google.maps.MapTypeId.SATELLITE
      }
      var map = new google.maps.Map(document.getElementById('map-canvas'),
                                    mapOptions);

      setMarkers(map, beaches);
    }

    google.maps.event.addDomListener(window, 'load', initialize);

    setInterval(function() { setMarkers(map, beaches); }, 5000);

</script>

What I simply want to do is reload only the markers. I tried reloading the map using initialize function but it didn't work. Then I tried to reloading using setMarkers function and still no luck...

Thanks for your help.


Solution

  • Few things you should do / things that I have changed from your original code:

    1. Use valid lat/lng coordinates for your markers (1121.28747820854187 for example is not a valid lng)
    2. Create a global variable for your map (easier to reference in your script)
    3. Create an array to hold your markers
    4. I have added a marker animation animation: google.maps.Animation.DROP, to your markers, so that you can see when they are reloaded, and a reload markers button to call the reload function.

    Basically what you want to do is:

    1. Create each marker within the setMarkers function
    2. Push each marker to the markers array
    3. When reloading your markers, loop through your markers array and call setMap(null) on each marker to remove it from the map
    4. Once done, call setMarkers again to re-draw your markers

    Updated code:

    let map;
    let markers = []; // Create a marker array to hold your markers
    const beaches = [
      ['Bondi Beach', 10, 10, 4],
      ['Coogee Beach', 10, 11, 5],
      ['Cronulla Beach', 10, 12, 3],
      ['Manly Beach', 10, 13, 2],
      ['Maroubra Beach', 10, 14, 1]
    ];
    
    function setMarkers(locations) {
    
      for (let i = 0; i < locations.length; i++) {
        let beach = locations[i];
        let myLatLng = new google.maps.LatLng(beach[1], beach[2]);
        const marker = new google.maps.Marker({
          position: myLatLng,
          map: map,
          animation: google.maps.Animation.DROP,
          title: beach[0],
          zIndex: beach[3]
        });
    
        // Push marker to markers array
        markers.push(marker);
      }
    }
    
    function reloadMarkers() {
    
      // Loop through markers and set map to null for each
      for (let i = 0; i < markers.length; i++) {
    
        markers[i].setMap(null);
      }
    
      // Reset the markers array
      markers = [];
    
      // Call set markers to re-add markers
      setMarkers(beaches);
    }
    
    async function initMap() {
      // Request libraries when needed, not in the script tag.
      const {
        Map
      } = await google.maps.importLibrary("maps");
    
      map = new Map(document.getElementById("map-canvas"), {
        zoom: 5,
        center: new google.maps.LatLng(10, 12),
        mapTypeId: google.maps.MapTypeId.SATELLITE
      });
      
      setMarkers(beaches);
    
      // Bind event listener on button to reload markers
      document.getElementById('reloadMarkers').addEventListener('click', reloadMarkers);
    }
    
    initMap();
    #map-canvas {
      height: 140px;
    }
    <div id="map-canvas"></div>
    <button id="reloadMarkers">Reload</button>
    <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: "AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk",
        v: "weekly",
        // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
        // Add other bootstrap parameters as needed, using camel case.
      });
    </script>

    JSFiddle demo