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: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:
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?)