2

I am creating a Visualforce component which holds a google map. The plan is to pass a list of addresses to this component and the map will place markers over these addresses.

Here is a sample visualforce component which shows markers for the hardcoded addresses :

<apex:component >

<apex:attribute name="addressList" type="String[]" description="array of addresses"/>

<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

<script type="text/javascript"> 

$(document).ready(function() {
    var myOptions = {
        center: new google.maps.LatLng(54, -2),
        zoom: 10,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    var map = new google.maps.Map(document.getElementById("map"), myOptions);
    var addressArray = [];
    addressArray = '{!addressList}';

    var geocoder = new google.maps.Geocoder();

    var markerBounds = new google.maps.LatLngBounds();

    for (var i = 0; i < addressArray.length; i++) {
        geocoder.geocode( { 'address': addressArray[i]}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                var marker = new google.maps.Marker({
                    map: map,
                    position: results[0].geometry.location
                });
                markerBounds.extend(results[0].geometry.location);
                map.fitBounds(markerBounds);
            } else {
                alert("Geocode was not successful for the following reason: " + status);
            }
        });
    }

});
</script>
<style>
    #map {
      font-family: Arial;
      font-size:12px;
      line-height:normal !important;
      height:500px;
      width: 800px;
      background:transparent;
    }
</style>

<div id="map"></div> 

</apex:component>

We can pass a List of addresses (as a List) to this component.

 <apex:page controller="MyCtrller">
    <c:MyMapComponent addressList="{!listOfAddresses}"/>
 </apex:page>

Where

  public class MyCtrller {
    public List<String> listOfAddresses {get; set;}

    public MyCtrller() {
       listOfAddresses = new List<String>();
       listOfAddresses.add('2001 Gemini St, Houston, TX');
       listOfAddresses.add('210 E Huron St, Ann Arbor');
       listOfAddress.add('45th Park Ave, New York');
    }
  }

However it gives me the following error:

   Geocode was not successful for the following reason: OVER_QUERY_LIMIT

and

   Geocode was not successful for the following reason: ZERO_RESULTS

Surprisingly if I hardcode the same addresses in the javascript like :

var addressArray = new Array("2001 Gemini St, Houston, TX" , "210 E Huron St, Ann Arbor", "45th Park Ave, New York");

it drops the markers on the respective locations.

I put an alert(addressArray) to check, but it seems addressArray is receiving the addresses correctly like this:

    [2001 Gemini St, Houston, TX, 210 E Huron St, Ann Arbor, 45th Park Ave, New York]

I do not understand how I am running out of query limits when I pass the addresses from a vf component. Or am I passing the addresses in an incorrect fashion?

2
  • Why have you hardcoded the addresses? for instance if we have 10 accounts then the addresses should be passed dynamically. Do you have any solution for that ?
    – user7045
    Feb 26 '14 at 10:59
  • The hardcoded address was just to show that the map code works. You can pass the addresses dynamically by querying them from the records. Apr 28 '14 at 19:19
1

So i figured it out finally. The addressArray received a long string of addresses and so it was unable to determine the location for them. The work around is to user in your javascript and push individual address in the addressArray.

Like this:

    var addressArray = new Array();
    <apex:repeat value="{!addressList}" var="address">
        addressArray.push("{!address}");
    </apex:repeat>

This will properly insert all the addresses in the array.

Note to reader: use google/firefox inspector more often for diagnosis.

1
  • Alternatively, you could JSON.serialize() the address list in the controller and put that in a property.
    – metadaddy
    Apr 27 '14 at 18:23
1

The program need to be changed in two places

in controller

 public class MyCtrller {
    public List<String> listOfAddresses {get; set;}

    public MyCtrller() {
       listOfAddresses = new List<String>();
       listOfAddresses.add('\"2001 Gemini St, Houston, TX\"');
       listOfAddresses.add('\"210 E Huron St, Ann Arbor\"');
       listOfAddresses.add('\"45th Park Ave, New York\"');
    }
  }

Please note the double quotes has to be added in each string

Now in component the variable declaration need to be changed as below

<apex:component >

<apex:attribute name="addressList" type="String[]" description="array of addresses"/>

<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

<script type="text/javascript"> 

$(document).ready(function() {
    var myOptions = {
        center: new google.maps.LatLng(54, -2),
        zoom: 10,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    var map = new google.maps.Map(document.getElementById("map"), myOptions);
   // var addressArray = [];  //  this line not required 
   // addressArray = '{!addressList}'; //this is invalid for creating array
    var addressArray = {!addressList};  // Use this format to fill addressArray 

    var geocoder = new google.maps.Geocoder();

    var markerBounds = new google.maps.LatLngBounds();

    for (var i = 0; i < addressArray.length; i++) {
        geocoder.geocode( { 'address': addressArray[i]}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                var marker = new google.maps.Marker({
                    map: map,
                    position: results[0].geometry.location
                });
                markerBounds.extend(results[0].geometry.location);
                map.fitBounds(markerBounds);
            } else {
                alert("Geocode was not successful for the following reason: " + status);
            }
        });
    }

});
</script>
<style>
    #map {
      font-family: Arial;
      font-size:12px;
      line-height:normal !important;
      height:500px;
      width: 800px;
      background:transparent;
    }
</style>

<div id="map"></div> 

</apex:component>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.