[SalesForce] Pass List from Class to VF Page Script

So, I'm trying to pass a list of strings from my apex class to my vf page, to use it on google maps API. The problem is that I can't pass the list containing my data. Here's my code:

Class

public with sharing class MapAccountExtension
{
    public List<Account> acc {get;set;}
    public String temp {get;set;}
    public List<String> location {get;set;}
    public Integer acclength {get;set;}
    
    public MapAccountExtension(ApexPages.StandardController controller) {
    }

    public MapAccountExtension()
    {
        acc = [SELECT Name, BillingStreet,BillingCity,BillingCountry FROM Account];
        List<String> location = new List<String>();
        system.debug(acc);
        acclength = acc.size();
        system.debug(acclength);
        for (integer i = 0; i <acclength ;i++)
        {
            temp = null;
            temp = acc[i].Name + ' , ' + acc[i].BillingStreet + acc[i].BillingCity + ' , ' + acc[i].BillingCountry;
            location.Add(temp); 
        }

        system.debug(location);
    }
    
}

VF Page with script

<apex:page standardController="Account" extensions="MapAccountExtension">
<head> 
    <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"/> 
</head> 
<body>
<div id="map" style="width: 800px; height: 600px;"></div>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript">
alert ('1st' + '{!location}');
var locationArray = new Array();
locationArray= '{!location}');
alert('2nd' + locationArray);
var delay = 100;
var infowindow = new google.maps.InfoWindow();
var latlng = new google.maps.LatLng(21.0000, 78.0000);
var mapOptions = {
    zoom: 5,
    center: latlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
var geocoder = new google.maps.Geocoder(); 
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
var bounds = new google.maps.LatLngBounds();

function geocodeAddress(address, next) {
geocoder.geocode({address:address}, function (results,status)
    { 
        if (status == google.maps.GeocoderStatus.OK) {
        var p = results[0].geometry.location;
        var lat=p.lat();
        var lng=p.lng();
        createMarker(address,lat,lng);
      }
      else {
          if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
          nextAddress--;
          delay++;
        } else {
                       }   
        }
      next();
    }
    );
}
function createMarker(add,lat,lng) {
  var contentString = add;
  var marker = new google.maps.Marker({
    position: new google.maps.LatLng(lat,lng),
    map: map,
          });

  google.maps.event.addListener(marker, 'click', function() {
    infowindow.setContent(contentString); 
    infowindow.open(map,marker);
   });

   bounds.extend(marker.position);

}
var nextAddress = 0;
function theNext() {
  if (nextAddress < locationArray.length) {
    setTimeout('geocodeAddress("'+locationArray[nextAddress]+'",theNext)', delay);
    nextAddress++;
  } else {
    map.fitBounds(bounds);
  }
}
theNext();
  
</script>
</body>
</apex:page>

If i set the location string passed to the api manually (created on javascipt), it resolves fine, so it really is that I cant pass the string to the javascript. What I'm doing wrong?

UPDATED: working sample

VF Page

<apex:page standardController="Account" extensions="MapAccountExtension">
  <head> 
    <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"/> 
</head> 
<body>
  <div id="map" style="width: 800px; height: 600px;"></div>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false">
 </script> 
 <script type="text/javascript">
  
  var locationString = {!locationsJson};
    
  var delay = 100;
  var infowindow = new google.maps.InfoWindow();
  var latlng = new google.maps.LatLng(39,-8);
  var mapOptions = {
    zoom: 6,
    center: latlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  var geocoder = new google.maps.Geocoder(); 
  var map = new google.maps.Map(document.getElementById("map"), mapOptions);
  var bounds = new google.maps.LatLngBounds();

  function geocodeAddress(address, next) {
    geocoder.geocode({address:address}, function (results,status)
      { 
         if (status == google.maps.GeocoderStatus.OK) {
          var p = results[0].geometry.location;
          var lat=p.lat();
          var lng=p.lng();
          createMarker(address,lat,lng);
        }
        else {
           if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
            nextAddress--;
            delay++;
          } else {
                        }   
        }
        next();
      }
    );
  }
 function createMarker(add,lat,lng) {
   var contentString = add;
   var marker = new google.maps.Marker({
     position: new google.maps.LatLng(lat,lng),
     map: map,
           });

  google.maps.event.addListener(marker, 'click', function() {
     infowindow.setContent(contentString); 
     infowindow.open(map,marker);
   });

   bounds.extend(marker.position);

 }

  var nextAddress = 0;
  function theNext() {
    if (nextAddress < locationString.length) {
      setTimeout('geocodeAddress("'+locationString[nextAddress]+'",theNext)', delay);
      nextAddress++;
    } else {
      map.fitBounds(bounds);
    }
  }
  theNext();
  
</script>
</body>
</apex:page>

Class

public with sharing class MapAccountExtension {

    public List<Account> acc {get;set;}
    public String temp {get;set;}
    public List<String> location {get;set;}
    public Integer acclength {get;set;}
    
    public MapAccountExtension(ApexPages.StandardController controller) {
    }
    
    public String locationsJson {
        get {
            String[] locations = new String[] {};
            for (Account a : [
                    SELECT Name, BillingStreet,BillingCity,BillingCountry
                    FROM Account
                    ORDER BY Name
                    LIMIT 1000
                    ]) {
                locations.add(a.Name
                        + ' , ' + a.BillingStreet
                        + ' ' + a.BillingCity
                        + ' , ' + a.BillingCountry
                        );
            }
            for (integer i= 0;i<locations.size();i++)
            {
                locations[i] = locations[i].replaceAll('\\n',' ');
            }
            return JSON.serialize(locations);
        }
        
    }
}

Best Answer

As well as how the location array is build (see Vamsi's answer) there is a problem in how the Apex array is turned into valid JavaScript. To get the embedded commas correctly escaped and ensure that the string rendered into the page in array in JavaScript (i.e. var locationArray = ['abc', 'def'];) you can use JSON formatting:

public with sharing class MapAccountExtension {

    public String locationsJson {
        get {
            String[] locations = new String[] {};
            for (Account a : [
                    SELECT Name, BillingStreet,BillingCity,BillingCountry
                    FROM Account
                    ORDER BY Name
                    LIMIT 1000
                    ]) {
                locations.add(a.Name
                        + ' , ' + a.BillingStreet
                        + ' , ' + a.BillingCity
                        + ' , ' + a.BillingCountry
                        );
            }
            return JSON.serialize(locations);
        }
    }
}

JSON is the native JavaScript format for representing data structures including arrays and objects.

Given the above Apex, in your JavaScript the assignment can be just this:

var locationArray = {!locationsJson};

When you think you have the code right, use your browser's "Inspect Element" to check the formatting and also check that there are no JavaScript errors in the JavaScript Console. (See How do I start to debug my own Visualforce/JavaScript?)

Related Topic