I’m trying to give a global variable a value after some code is processed. It’s not working as planned.
What I do is enter an address and city in two textboxes. It goes into the last function and calls codeAddress which gets the coordinates of the address.
From there i send the coordinates to setLatLng and it works fine. But i can’t call longlats using the getLatLng to see the set value.
It’ll only show a value if I add an address and city two times. I’m thinking the longlats are being initialized too late that I don’t see the correct value in time.
Any advice?
Relevant code is below.
<script>
var longlats ="";
function setLatLng(x,y){
longlats = x+","+y;
alert(longlats) //shows value
}
function getLatLng(){
alert(longlats);
return longlats;
//calling this gives undefined
}
function codeAddress() {
$('#map').show();
var geocoder = new google.maps.Geocoder();
var address = document.getElementById("address").value +"," + document.getElementById("city").value;
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();
locationsall[counter] = new Array();
locationsall[counter][0] = address;
locationsall[counter][1] = lat; //has value
locationsall[counter][2] = lng; //has value
setLatLng(locationsall[counter][1],locationsall[counter][2]);
counter++;
}
$(function() {
$("#locationadd").click(function() {
codeAddress();
var get = getLatLng();//value is undefined..
//i want to do stuff with the values in longlats
}
)};
</script>
Edit1
$("#locationadd").click(function() {
var address = $("#address").val();
var city = $("#city").val();
if (address =="" || city =="") {
$("#locationtext").text('*Please enter an address and city');
return false;
}
else {
codeAddress(function(){
var get = getLatLng();
var longlat = get.split(",");
var lat = longlat[0];
var lng = longlat[1];
var $tr2 = $('<tr>').css({
'padding': '4px',
'background-color': '#ddd'
}).appendTo('#locationDeals');
var location = [
address,
city
];
locations.push(location);
for (i = 0; i < 2; i++) {
var $td2 = $('<td>').appendTo($tr2);
$('<span>').text(location[i]).appendTo($td2);
$('<input type="hidden">').attr({
'name': 'loc[' + ctr + '][' + i + ']',
'value': location[i]
}).appendTo($td2);
}
var $tdRemoveRow2 = $('<td>').appendTo($tr2);
$('<a>').attr({
'href': '#',
'id': 'submit-button'
}).text("Remove").click(function() {
var index2 = $tr2.index();
$("#locationDeals input[type='hidden']").each(function() {
this.name = this.name.replace(/\[(\d+)\]/, function(str2, number2) {
return "[" + (+number2 > index2 - 1 ? number2 - 1 : number2) + "]";
});
});
$tr2.remove();
var tmp = locations.splice(locations.indexOf(location), 1);
deleteMarker(tmp);
return false;
}).appendTo($tdRemoveRow2);
ctr++;
document.getElementById("address").value = "";
document.getElementById("city").value = "";
document.getElementById("address").focus();
$("#locationtext").text('');
return false;
});
}
});
The problem is
geocoder.geocodeis asynchronous. You can’t do it the way you do because yourcodeAddressfunction will return beforelonglatsis set. You need to change your coding style to use longlats only after google maps have returned the result.You need to change your code from this:
To this:
In order to do that, you need to change
copyAddressto:Additional explanation:
From your comments, it appears that you’re still trying to do this:
This won’t work because codeAddress returns BEFORE getLatLng executes. You need to change the style of your coding. You need to write it like this:
That is, you need to move all code that you would have written after the call to codeAddress to the function INSIDE codeAddress.
The reason for it is that the way the code executes is something like this:
BROWSER ENTERS JAVASCRIPT PHASE:
javascript phase ends, BROWSER ENTERS DOM RENDERING PHASE
DOM rendering ends, BROWSER ENTERS NETWORK PHASE
network phase ends, BROWSER ENTERS JAVASCRIPT PHASE
javascript phase ends, BROWSER ENTERS DOM RENDERING PHASE
and the event loop continues.
As you can see, you can’t simply return the values from codeAddress. Instead you need to move your code inside codeAddress to have it executed at the right time.