React/Javascript - Wait for variable to populate before running function - javascript

I am using a Google autocomplete geocoding input. I have it set up to handle the geocoding on change of the input(location selected), but also if the user hits the submit button after typing in a location without selecting from the autocomplete results. Once I get the user's selected location I am passing the lat/lng coordinates to the state of the parent component using a function updateParentState() What I would like to do is wait for the lat and lng variables to be populated before running that function. Currently the autocomplete portion of the function, the if (place.geometry) part of the condition, is working since lat/lng are populated instantly on change, but since Geocoding the raw input takes a bit, the updateParentState() function is running before lat/lng are populated. How can I adjust for this:
geocodeLoc = (place) => {
var self = this;
let lat = '';
let lng = '';
if (place.geometry) {
// WORKS
lat = place.geometry.location.lat();
lng = place.geometry.location.lng();
} else {
let geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': place.name}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
// DOESN'T WORK
lat = results[0].geometry.location.lat();
lng = results[0].geometry.location.lng();
}
});
}
self.props.updateParentState(
lat, lng
);
}

Call self.props.updateParentState in the callback of geocoder.geocode as well as at the end of the if block:
geocodeLoc = (place) => {
var self = this;
if (place.geometry) {
const lat = place.geometry.location.lat();
const lng = place.geometry.location.lng();
self.props.updateParentState(lat, lng);
} else {
let geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': place.name}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
const lat = results[0].geometry.location.lat();
const lng = results[0].geometry.location.lng();
self.props.updateParentState(lat, lng);
}
});
}
}

Related

Variable overwritten by ajax response

Using Google Maps and the Geocoder, I'm trying to loop over an object of addresses, return LatLng addresses for them, and create markers using both the original details and the latlng address in the setMarker function below.
The problem is, the response[a] is being overwritten by the last address in the object, because the for loop is running ahead of the AJAX results being returned.
How can I save the data in the current response[a] being looped over, so that when setMarker() is later called, it contains the right information?
Thanks
var limit = 0;
for (a in response){
if(limit<5){ // limit API calls
var addr = [response[a].Addr1, response[a].City, response[a].Zip];
geo = new google.maps.Geocoder();
geo.geocode({
address: addr.join(", "),
componentRestrictions: {
// country: 'UK'
}
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK && results) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
var latlng = new google.maps.LatLng(latitude, longitude);
if(latitude!="" && longitude!=""){
bounds.extend(latlng);
map.fitBounds(bounds);
_this.setMarker(map, limit, latlng, response[a]);
}
} // if geo results
});
}
limit++;
}
The problem you are facing is a classic one that can be solved using closure function.
Current code looks something like :
var a[20];
for(i=0;i<20;i++) {
some_async_method() {
//code that uses 'a[i]'
}
}
Using closure to preserve the scope of var a inside a async function :
var a[20];
for(i=0;i<20;i++) {
(function(_a){
some_async_method() {
//code that uses 'a[i]' as '_a'
}
})(a[i]);// self calling function that preserves the scope of a[i]
}
So your code will look like :
var limit = 0;
for (a in response){
if(limit<5){ // limit API calls
var addr = [response[a].Addr1, response[a].City, response[a].Zip];
geo = new google.maps.Geocoder();
(function(response_a){ // closure function to preserve scope of 'response[a]'
geo.geocode({
address: addr.join(", "),
componentRestrictions: {
// country: 'UK'
}
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK && results) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
var latlng = new google.maps.LatLng(latitude, longitude);
if(latitude!="" && longitude!=""){
bounds.extend(latlng);
map.fitBounds(bounds);
_this.setMarker(map, limit, latlng, response_a);
}
} // if geo results
});
})(response[a]);
}
limit++;
}

JS geocoder API

Hi I'm trying to get latLon of searched location but the console log is saying that google is not defined can someone point me why its giving me that error. Read the doc on google but this code is similar to what they have.
var searchLocation = 'london';
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': searchLocation
}, function(result, status) {
if (status == google.maps.GeocoderStatus.OK) {
var lat = result[0].geometry.location.lat();
var lon = result[0].geometry.location.lng();
callback();
console.log(lat + ', '+ lon);
}
});
http://jsfiddle.net/4fm8715z/1/ (view console log)

How to get address from lat and lng?

I have two set of lat and lng.
I want both address and stored in some variable:
var geocoder = new google.maps.Geocoder();
for(var i=0; i<json_devices.length; i++)
{
var lat = json_devices[i].latitude;
var lng = json_devices[i].longitude;
console.log(lat);
console.log(lng);
var latlng = new google.maps.LatLng(lat,lng);
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
address=results[1].formatted_address;
} else {
alert('No results found');
}
} else {
alert('Geocoder failed due to: ' + status);
}
});
console.log(address);
}
In this, lat & lan get correctly. But address are not stored in variable. What is the mistake?
I am using this method and it is working perfect for me.
Please have a look on it.
public String getAddressFromLatLong(GeoPoint point) {
String address = "Address Not Found";
Geocoder geoCoder = new Geocoder(
getBaseContext(), Locale.getDefault());
try {
List<Address> addresses = geoCoder.getFromLocation(
point.getLatitudeE6() / 1E6,
point.getLongitudeE6() / 1E6, 1);
if (addresses.size() > 0) {
address =addresses.get(0).getAddressLine(0);
if(address.length()<=0)
address =addresses.get(0).getSubLocality();
}
}
catch (Exception e) {
e.printStackTrace();
}
return address;
}
Here the Google geocode is asynchonous type of function call.
From DOCS:
Accessing the Geocoding service is asynchronous, since the Google Maps
API needs to make a call to an external server. For that reason, you
need to pass a callback method to execute upon completion of the
request. This callback method processes the result(s). Note that the
geocoder may return more than one result.
So you can't get the address like that, instead use the common approach called callback.
Here I have created a sample code to explain the process, which can be altered by yourself.
var geocoder;
function codeLatLng(callback) {
geocoder = new google.maps.Geocoder();
var input = document.getElementById("latlng").value;
var latlngStr = input.split(",", 2);
var lat = parseFloat(latlngStr[0]);
var lng = parseFloat(latlngStr[1]);
var latlng = new google.maps.LatLng(lat, lng);
geocoder.geocode({
'latLng': latlng
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
address = results[1].formatted_address;
callback(address);
} else {
alert("No results found");
}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
$('input[type="button"]').on('click', function () {
codeLatLng(function (address) { //function call with a callback
console.log(address); // THE ADDRESS WILL BE OBTAINED
})
});
JSFIDDLE

Helper function of a controller does not return anything

I have a function in my map controller to convert an address to a google.maps.latlng and I want to return this value, but my function doesn't return anything. I think thats because the values change inside another function, but I can't figure out how to solve this.
addressToLatLng: function(address) {
var geocoder = new google.maps.Geocoder(), lat, lng, latlng;
geocoder.geocode({ 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
lat = results[0].geometry.location.lat();
lng = results[0].geometry.location.lng();
latlng = new google.maps.LatLng(lat, lng);
console.log(latlng); // will give me the object in the log
}
});
return latlng; // nothing happens
},
That's because the geocode call is asynchronous, so you are trying to return the value before it exists.
You can use a callback for the caller to get the value when it arrives:
addressToLatLng: function(address, callback) {
var geocoder = new google.maps.Geocoder(), lat, lng, latlng;
geocoder.geocode({ 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
lat = results[0].geometry.location.lat();
lng = results[0].geometry.location.lng();
latlng = new google.maps.LatLng(lat, lng);
callback(latlng);
}
});
},
Usage:
yourController.addressToLatLng(address, function(latlng){
console.log(latlng);
});

can create a google map by lat, long in jquery . google maps api

i have lat, long values of a place . how can i create a google map for that lat , long using googl maps api , jquery
is this possible ??
currently iv am getting the lat , long values using
var address = jQuery('#business-address').val();
var city = jQuery('.city').val();
var state = jQuery('.state').val();
var country = jQuery('.country').val();
var address_string = address+","+city+","+state+","+country;
var geocoder = new google.maps.Geocoder();
if (geocoder) {
geocoder.geocode({ 'address': address_string }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
alert(results[0].geometry.location);
}
else {
alert("Geocoding failed: " + status);
}
});
}

Categories