how to change value of a var in reverse geocoding function [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Google map sync geocode delay
(2 answers)
Closed 4 years ago.
I am trying to get address info for my project. I can see the address by alert() method if i write it inside the geocode function. but if i outside of the function, it returns undefined.
tried to write the variable name like window.adres but didnt work. i think because of an another function with is parent of this.
how to make that variable global and change the value?
var geocoder = new google.maps.Geocoder;
var adres;
var latlng = {lat: parseFloat(lat), lng: parseFloat(lon)};
geocoder.geocode({'location': latlng}, function(results, status) {
if (status === 'OK') {
if (results[0]) {
adres = results[0].formatted_address;
//window.adres = ... is not working. i think because of an another function which is parent of these lines.
alert(adres); //returns address
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
alert(adres); //returns undefined
also i tried that
var geocoder = new google.maps.Geocoder;
var latlng = {lat: parseFloat(lat), lng: parseFloat(lon)};
var adres = geocoder.geocode({'location': latlng}, function(results, status) {
if (status === 'OK') {
if (results[0]) {
return results[0].formatted_address;
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
alert(adres); //returns undefined too

If you set a global variable with window dot whatever, you will be able to get to it later by calling the same (fully qualified) variable.
Here is an example that proves this (run the snippet to see it in action).
function setVarInFunction(){
window.adres = 'here is some text';
}
console.log(window.adres); // should be undefined
setVarInFunction();
console.log(window.adres); // now there should be something
The reason alert(adres) is not working the way you expect is that:
you create a variable at the beginning
you execute an asynchronous request off to Google to do some work, and update your variable when it comes back from Google
you execute your alert to show the var value, but you have no guarantee that Google has actually responded yet with it's data (it almost certainly has not yet responded)
What do you want to do with that value? You almost certainly don't want to just alert() it, right? Whatever you want to do with it, you should do in the block where it comes back from Google with success or failure.

You are missing the ending of your anonymous function.
This is an issue related to the callbacks in javascript.
Geocoder takes time to process your request. Thus, you alert address while it is not yet defined.
I have updated your code to new coding standards and added comments :
let geocoder = new google.maps.Geocoder;
let latlng = { lat: parseFloat(lat), lng: parseFloat(lon) };
let address = null;
// 1. The geocoder starts the process to find the address
geocoder.geocode({'location': latlng}, (results, status) => {
// 3. The geocoder finally located the address, because it takes time.
if (status === 'OK') {
if (results[0]) {
// This updated the variable with the correct result.
address = results[0].formatted_address;
// You should call here a new function, in order to do the rest of your work
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
// 2. you output address
alert(address); // This won't work as address is set by the geocoder which is asynchronous
Hope this helps.

Related

Getting a Return Value From Google Maps Geocoder [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 8 years ago.
I am trying to get a location name according to a lat-long coordinate from the Google maps geocoder. I cannot seem to extract the value from the geocoder callback. Here is my code:
geocoder = new google.maps.Geocoder();
var address = "";
var lat = 54.1234;
var lng = -114.1234;
var latlng = new google.maps.LatLng(lat, lng);
geocoder.geocode({'latLng': latlng } , function(results,status) {
if (status == google.maps.GeocoderStatus.OK) {
address = results[1].formatted_address; //want to get this address
} else {
address = 'error';
}
});
window.alert(address)
//address is an empty string here, but I want the value from inside the geocoder
//want access to address here to do other operations with it
The documentation for geocoder on the Google Developers site is almost non existant,
and I am having problems trying to find an example that is similar. I am out of my comfort area here, so any help
would be great!
The call is asynchronous, so the value exists inside the callback function:
geocoder.geocode({'latLng': latlng } , function(results,status) {
if (status == google.maps.GeocoderStatus.OK) {
address = results[1].formatted_address; //want to get this address
} else {
address = 'error';
}
window.alert(address);
});
// The code here runs before the callback function

How to assign a value to an outer variable from an inner function in javascript? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
So, I have this piece of code:
function centermap(){
var geocoder = new google.maps.Geocoder();
var address = document.getElementById('office_address').value;
var new_location = "";
geocoder.geocode( {'address': address}, function(results, status, new_location) {
if (status == google.maps.GeocoderStatus.OK) {
new_location = results[0].geometry.location;
console.log(new_location); // output is fine here
}
else {
console.log("Geocode was not successful for the following reason: " + status);
}
})
console.log(new_location); // output is "" - which is the init value
return new_location // the returned object is also ""
};
$("input[id=office_address]").change(function(){
var coordinates = new Array();
var location = centermap();
coordinates.push(location.geometry.location.lat());
coordinates.push(location.geometry.location.lng());
map.setView(coordinates, 14);
});
What am I not getting regarding the scopes here? How can I set the "outside" new_location to be the gecode result? Please feel free to point all the mistakes on my understanding on this
EDIT: I have read the answers on this and this so questions but I didn't manage to do what I want.
As somebody pointed out in the comments, the geocode function is asynchronous, so as soon as it is executed it will return without any value.
Consider this workflow:
...
geocoder.geocode( ... );
// this is executed straight after you call geocode
console.log(new_location);
...
...
// probably at a certain point here your geocode callback is executed
function(results, status, new_location) {
if (status == google.maps.GeocoderStatus.OK) {
...
});
The important thing is to pass a callback function to your centermap as well:
$("input[id=office_address]").change(function(){
var coordinates = new Array();
// pass a callback to execute when geocode get the results
centermap(function (location){
coordinates.push(location.geometry.location.lat());
coordinates.push(location.geometry.location.lng());
map.setView(coordinates, 14);
});
});
function centermap(callback){
var geocoder = new google.maps.Geocoder();
var address = document.getElementById('office_address').value;
geocoder.geocode( {'address': address}, function(results, status) {
var new_location = '';
if (status == google.maps.GeocoderStatus.OK) {
new_location = results[0].geometry.location;
console.log(new_location); // output is fine here
}
else {
console.log("Geocode was not successful for the following reason: " + status);
}
// at this point we return with the callback
callback(new_location);
});
// everything here is executed before geocode get its results...
// so unless you have to do this UNRELATED to geocode, don't write code here
};

Return value with google maps geocoder [duplicate]

This question already has answers here:
How do I return a variable from Google Maps JavaScript geocoder callback?
(5 answers)
Closed 9 years ago.
I just can't find what's wrong with this bit of code:
function getLocationName(latitude, longitude) {
if (isNaN(parseFloat(latitude)) || isNaN(parseFloat(longitude))) {
return false;
}
var locationName;
var geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(latitude, longitude)
// Reverse Geocoding using google maps api.
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
locationName = results[1].formatted_address;
alert(locationName);
}
else {
locationName = "Unknown";
}
}
else {
locationName = "Couldn't find location. Error code: " + status;
}
});
alert(locationName);
return locationName;
}
I call this from a jquery event handler like this:
$("#id").on("event", function (event, ui) {
$("#userLocation").text(getLocationName(latitude, longitude));
});
Weird part is that the first alert gets the correct value of 'locationName' but the second one always returns 'undefined'. I tried initializing the variable with a value and in that case the first alert again returned the correct location name but the second one returned the initialization value. This gives me a notion that this might be a variable scope related problem but I just can't figure what.
PS. I don't have any other variables (local/global) by the same name.
Update: The alert works fine now (thanks to Lwyrn's answer) but the return value is still wrong. I've followed the answers in the linked SO question and still I couldn't 'return' the right value. The alert did work fine.
You have to move "alert(locationName);" into the geocoder.geocode callback. Because geocoder.geocode executes an AJAX request. When you throw the alert the var locationName is still undefined (not set).
Try it like this
function getLocationName(latitude, longitude, callback) {
if (isNaN(parseFloat(latitude)) || isNaN(parseFloat(longitude))) {
return false;
}
var locationName;
var geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(latitude, longitude)
// Reverse Geocoding using google maps api.
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
locationName = results[1].formatted_address;
alert(locationName);
}
else {
locationName = "Unknown";
}
}
else {
locationName = "Couldn't find location. Error code: " + status;
}
alert(locationName);
callback(locationName);
});
}
To get the "return" you have to create a your own callback.
Try like this
$("#id").on("event", function (event, ui) {
getLocationName(latitude, longitude, function(result){
$("#userLocation").text(result);
});
});
As for the alert, the return is called before the ajax request. So you have to use a callback to be called when the ajax request has done his job!

How do you return a latitude and longitude array using the Google Javascript v3 Geocoder? [duplicate]

This question already has answers here:
Accessing array from outside of geocode loop
(2 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 10 years ago.
I'm trying to create a function that utilizes Google Javascript V3's geocoding capabilities and returns an array with the longitude and latitude. For some reason the return array is not being populated using the function. Thanks for your help!
Code:
function getCoords(address) {
var latLng = [];
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
latLng.push(results[0].geometry.location.lat());
latLng.push(results[0].geometry.location.lng());
return latLng;
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
var test_arr;
test_arr = getLatLng('New York');
alert(test_arr[0] + ',' + test_arr[1]) // I'm getting a test_arr is undefined here.
Read up on using callback functions in Javascript. This article might be helpful.
As Jon pointed out, you can solve this by passing a callback function into your getCoords method. It's a way of waiting for the response to come back from Google. You define a function that will be called when the geocoding is done. Instead of returning the data, you'll call the provided function with the data as an argument.
Something like this:
function getCoords(address, callback) {
var latLng = [];
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
latLng.push(results[0].geometry.location.lat());
latLng.push(results[0].geometry.location.lng());
callback(latLng);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
getCoords('New York', function(latLng) {
var test_arr;
test_arr = latLng;
alert(test_arr[0] + ',' + test_arr[1])
// Continue the rest of your program's execution in here
});
#Matt Ball should have posted the answer. :)
The reason test_arr is undefined is because you're evaluating it immediately before the results come back.
If you did a setTimeout (which you shouldn't do), you would notice eventually the array will have something in it.
setTimeout(function(){
alert(test_arr) // has stuff...
}, 5000);
Instead, you can pass an anonymous function to getCoords as a callback. This function gets executed once the coordinates are available.
function getCoords(address, callback) {
...
var lng = results[0].geometry.location.lng();
var lat = results[0].geometry.location.lat();
callback([lat, lng]);
...
}
getCoords("New York", function(coords) {
alert(coords); // works
});

google maps geocoding and order of initialization

so I've run into a problem recently, and maybe you guys can help.
So to start off, I've created website and a marker, and I'm trying to retrieve the center point to reverse-geocode the address.
My code is below :
function ReverseGeocode(lat, lng)
{
var latlng = new google.maps.LatLng(lat, lng);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({"latLng": latlng}, function(results, status)
{
if (status != google.maps.GeocoderStatus.OK)
{
alert("Geocoding has failed due to "+ status);
}
address = results[0].formatted_address;
});
}
The problem I'm having here, is when I try to pass "address" back out (address is right now a global variable) all I get is "undefined".
Here's the code where I'm trying to pass it back out:
sendString += '&lat=' + lat;
sendString += '&lng=' + lon;
ReverseGeocode(center.lat(), center.lng());
alert(""+address);
sendString += '&address=' + address
var currentLang = "en"
sendString += '&phone=' + document.getElementById("number").value;
sendString += '&email=' + document.getElementById("email").value;
sendString += ($("prefsms").checked)?'&contactMethod=sms':'&contactMethod=email';
sendString += '&serviceType=' + document.getElementById("serviceType").value;
sendString += '&language=' + currentLang;
alert(""+sendString);
In my alert box, all I get is "undefined". Yet, if I add another alert box INTO the ReverseGeocode function, I'll get the address in an alert box, but this occurs AFTER the alert box in the outside function.
Any ideas as to what's going on? I would have thought that the alert box inside the ReverseGeocode function would go first, not the other way around.
Thanks!
As Heitor Chang said, Geocoding is asynchronous - so when you try to return the address, it get's returned to the function you pass as a callback to geocoder.geocode(). Confused? see this:
function ReverseGeocode(lat, lng)
{
var latlng = new google.maps.LatLng(lat, lng);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({"latLng": latlng}, function(results, status)
{
if (status != google.maps.GeocoderStatus.OK)
{
alert("Geocoding has failed due to "+ status);
}
return results[0].formatted_address; // this is how you might've been returning (i am just assuming since you didn't provide any code that returns address.
});
}
Now you can see that it gets returned to the function you are passing to geocoder.geocode()
What you should be doing is use callbacks - you are passing one here, probably without realising it - accept a callback as the third argument to ReverseGeocode function and when you get the result as OK, call the callback and return the address. Here's how:
function ReverseGeocode(lat, lng, cb) // cb - callback, a function that takes the address as an argument.
{
var latlng = new google.maps.LatLng(lat, lng);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({"latLng": latlng}, function(results, status)
{
if (status != google.maps.GeocoderStatus.OK)
{
alert("Geocoding has failed due to "+ status);
}
cb(results[0].formatted_address); // call the callback passing to it the address and we're done.
});
}
How to use it? This way:
ReverseGeocode( LAT, LNG, function(address) {
// do something with the address here. This will be called as soon as google returns the address.
});
(Reverse) Geocoding is asynchronous, meaning the request goes to Google servers, your script keeps running, and the code inside result is OK block executes when Google sends back its reply. The overall execution won't necessarily follow the order of commands in the order it was written.
To use the value of address your code has to be included in that code block where the status returned is OK.

Categories