Search code examples
javascriptgoogle-mapsaxiosgeocode

How to show multiple markers from a list of names


javascript

       function loadMap(){
                  <!--set Map Options -->
                     var options = {
                    zoom: 9
                    };

          <!--New map-->
              var map = new google.maps.Map(document.getElementById('map'), options );

          <!--Get location to put marker-->
              var locations = document.querySelectorAll("[id='playgroundName']");

          var bounds= new google.maps.LatLngBounds();
          var infoWindow = new google.maps.InfoWindow();
          var marker = new google.maps.Marker();
          var infoWindowContent;

          <!-- Calculate Latitude and Longitude for location -->
          for (i=0; i!=locations.length; i++){
           var loc = locations[i].value;
              axios.get('https://maps.googleapis.com/maps/api/geocode/json',{
                            params:{
                                    address:locations[i].value,
                                    key:'Your_Key'
                                    }
                            })
                            .then(function(response){
                            // Geometry
                            var lat = response.data.results[0].geometry.location.lat;
                            var lng = response.data.results[0].geometry.location.lng;

                <!-- Add marker -->
                 marker[i] = new google.maps.Marker({
                            position : {lat: lat, lng: lng},
                            map : map,
                            title: loc
                 });

                  <!-- Info window for marker -->
                  infoWindowContent= {content:'<h4> ' + marker[i].title +' </h4>'};
                  infoWindow[i] = new google.maps.InfoWindow( infoWindowContent );
                  marker[i].addListener('click', function(){
                            infoWindow.open(map, marker[i]);
                  });

                  <!-- Form a boundary for map -->
                  bounds = new google.maps.LatLngBounds();
                  bounds.extend(marker[i].getPosition());

                  <!-- Fit all markers on a map -->
                   map.setCenter(bounds.getCenter());
                   map.fitBounds(bounds);
  });

  }

                  map.setZoom(9);
}

var locations = document.querySelectorAll("[id='playgroundName']"); is passed from thymeleaf. one of the locations.value = "Amberg Park" or "Barrett Brothers Park" which is one of the names of the park I want to mark on maps. I need to create array of lat/lang for each name, and put markers with this array

This code displays markers on google map but every marker has same name, infowindow displays same(last) infowindowcontent for every marker. Fit bounds doesn't work as well. Reason must be cannot use for loop i variable inside callback function. I tried using different function to get array of location, that didn't work well either.

I also tried geocoder.geocode() as well to get lat and lang. I don't mind using axios/geocode() as long as I get lat/lang for individual marker.


Solution

  • This is just a sample code for those who are struggling. I have 3 different arrays which I need to process something else for later, so pl don't judge the code.

    Problem here was, JavaScript was asynchronously loading all the code without waiting for geocode to work. So putmarkers function was executing before getting any lat/lang. To make sure geocode gets lat/lang for all the locations I have used recordsLength variable.

    var locationLat = new Array();
    var locationLng = new Array();
    var locationAddress = new Array();
    var map;
    var recordsLength;
    
    function loadMap(){
      var options = {
        zoom: 1
      };
    
      map = new google.maps.Map(document.getElementById('map'), options );
    
      var locations = document.querySelectorAll("[id='playgroundName']");
      hasGeocoded= false;
      length = locations.length;
    
      for (i=0; i!=locations.length; i++){
        var address = locations[i].value;
        var geocoder =  new google.maps.Geocoder();
        geocoder.geocode( { 'address': address}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            var lat = results[0].geometry.location.lat();
            var lng = results[0].geometry.location.lng();
            var add = results[0].formatted_address;
            createLatLngArray(lat,lng, add);
            }
        });
      }
    }
    
    function createLatLngArray(lat, lng, add){
        locationLat.push(lat);
        locationLng.push(lng);
        locationAddress.push(add);
    
        if(locationLat.length == recordsLength)
            {
            putMarkers();
            }
    
        }
    
    function putMarkers(){
        var infowindow = new google.maps.InfoWindow();
        var bounds = new google.maps.LatLngBounds();
    
        var marker, i;
    
        for (i = 0; i < locationLat.length; i++) {
        marker = new google.maps.Marker({
             position: new google.maps.LatLng(locationLat[i], locationLng[i]),
             map: map
        });
        marker.setMap(map);
    
        google.maps.event.addListener(marker, 'click', (function(marker, i) {
         return function() {
             infowindow.setContent(locationAddress[i]);
             infowindow.open(map, marker);
         }
        })(marker, i));
        bounds.extend(marker.getPosition());
        }
        map.fitBounds(bounds);
    }