Jquery Form Submit, Async Call then Submit Form On Success - javascript

I am trying to get the lat long of an address inserted into the form before the form is submitted.
Here is my code:
var success = false;
var getLat = 0;
var getLng = 0;
function getLngLat() {
var address = $(".save-new-address").val();
if(!address) return false;
if(success) return false;
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
console.log(results);
map.setCenter(results[0].geometry.location);
success = true;
var newMarker = new google.maps.Marker({
position: results[0].geometry.location,
map: map
});
$(".save-new-lat").val(results[0].geometry.location.lat);
$(".save-new-lng").val(results[0].geometry.location.lng);
} else {
alert("Geocode was not successful for the following reason: " + status);
};
});
}
$("form#save-new-restaurant").submit(function () {
getLngLat();
if(success) {
return true;
} else {
getLngLat();
$("form#save-new-restaurant").submit();
return false;
}
});
Most of it is just copied from the google developers page. However what I am finding is either the form is submitting too quick, and the details are being retrieved after the above function has finished,
I am just trying to get the data from google when the form is submitted, and when i've got the data I want to then submit the form. How can I do this?

Try this instead
var success = false;
var getLat = 0;
var getLng = 0;
function getLngLat() {
var address = $(".save-new-address").val();
if(!address) return false;
if(success) return false;
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
console.log(results);
map.setCenter(results[0].geometry.location);
success = true;
var newMarker = new google.maps.Marker({
position: results[0].geometry.location,
map: map
});
$(".save-new-lat").val(results[0].geometry.location.lat);
$(".save-new-lng").val(results[0].geometry.location.lng);
$("form#save-new-restaurant").unbind("submit"); // unbinding event so getLngLat doesn't execute again
document.getElementById('save-new-restaurant').submit();
$("form#save-new-restaurant").bind("submit", formSubmitCallBack); // attaching event for further uses if require
} else {
alert("Geocode was not successful for the following reason: " + status);
};
});
}
$("form#save-new-restaurant").bind("submit", formSubmitCallBack);
function formSubmitCallBack() {
getLngLat();
return false;
}
Hope this will help !!

You could use a deferred object.
https://api.jquery.com/jquery.deferred/
$("form#save-new-restaurant").submit(function () {
var lngLat = getLngLat();
$.when(lngLat)
.done(function() {
return true;
})
.fail(function() {
//handle failure
});
}
Then in your other code
function getLngLat() {
//stuff
var deferred = $.Deferred();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
//do stuff
deferred.resolve();
} else {
deferred.reject();
}
}
return deferred;
}

Related

Undefined Issue using Google's Javascript API

I've been stuck on an issue for a number of days when using the google geo-location api. This is what I've been trying -
function codeAddress(address) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({"address": address}, function(results, status) {
if (status == "OK") {
return results[0].geometry.location;
} else {
return null;
}
});
}
function generateJSON(origin, destination) {
var origin_loc = codeAddress(origin);
var dest_loc = codeAddress(destination);
....
}
The "origin_loc" variable is coming back unassigned and I haven't been able to figure out why with the debugger. When I log the results[0] to the console it is coming back fine with the object.
Does anyone have any ideas why this is happening?
Thanks
This is what worked for me in the end -
function codeAddresses(addresses, callback) {
var coords = [];
for(var i = 0; i < addresses.length; i++) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'address':addresses[i]}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
coords.push(results[0].geometry.location);
if(coords.length == addresses.length) {
callback(coords);
}
}
else {
throw('No results found: ' + status);
}
});
}
}
function generateJSON(origin, destination) {
var addresses = [origin, destination];
codeAddresses(addresses, function(coords) {
var json = { ..... }
....
});
}
Thanks for your help #yuriy636!

GoogleMaps API Geocoding Callback

A simple one that I cannot seem to get to work properly.
I have the following:
function geocode(address, callback) {
if (typeof (geocoder) == 'undefined') geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
callback({ Latitude: results[0].geometry.location.lat(), Longitude: results[0].geometry.location.lng() });
}
else {
callback(0);
console.log("Geocode was not successful for the following reason: " + status);
}
});
}
That gets called by:
var latitude = '';
var longitude = '';
geocode(self.address(), function (result) {
if (result === 0) {
//Error with geocoding
}
else {
latitude = result.Latitude;
longitude = result.Longitude;
}
});
//Do some stuff with latitude and longitude
Now, the results do return, however they do so asynchronously which is what I thought the callback would overcome e.g. latitude and longitude value are undefined.
I think this i the correct way
var latitude = '';
var longitude = '';
geocode(self.address(), function (result) {
if (result === 0) {
//Error with geocoding
}
else {
....
manage your latitude, longitude
....
}
});
function geocode(address) {
if (typeof (geocoder) == 'undefined') geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
latitude = results[0].geometry.location.lat();
longitude =results[0].geometry.location.lng() });
}
else {
console.log("Geocode was not successful for the following reason: " + status);
}
});

How to get the result from an anonymous function in Javascript?

I'm using a simple script to geocode addresses.
var geocoder;
var departure;
var arrival;
function initialize() {
geocoder = new google.maps.Geocoder();
}
google.maps.event.addDomListener(window, 'load', initialize);
function geocode(options) {
var address = options.address.val() || null;
var result = {};
if (address) {
geocoder.geocode( { 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
result.lat = results[0].geometry.location.lat();
result.lng = results[0].geometry.location.lng();
} else {
result.lat = null;
result.lng = null;
}
});
}
}
function geocode_all() {
departure = geocode({
address: $('#departure')
});
//console.log(departure);
arrival = geocode({
address: $('#arrival')
});
//console.log(arrival);
}
I would like that my departure variable and my arrival variable to be object with the resulting latitude and longitude.
How should I proceed as my result variable is out of scope?
Thanks !
The problem isn't that the function is anonymous, and it isn't scope; the problem is that the Google geolocation API is asynchronous. It's impossible for your geocode function to return its result; instead, just like Google's function, it must accept a callback that it calls back with the result later, when the result is known. (Or it can use callbacks indirectly, via the "promise" pattern, but the fundamental concept is the same.)
So, using a callback:
function geocode(options, callback) {
// ^--- Accept the callback
var address = options.address.val() || null;
var result = {};
if (address) {
geocoder.geocode( { 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
result.lat = results[0].geometry.location.lat();
result.lng = results[0].geometry.location.lng();
} else {
result.lat = null;
result.lng = null;
}
callback(result); // <== Call it
});
}
}
// usage
geocode({/*...*/}, function(result) {
// This gets called later, asynchronously, with the result
});
Or using a jQuery Deferred/Promise:
function geocode(options) {
var d = new $.Deferred(); // <== Create the deferred
var address = options.address.val() || null;
var result = {};
if (address) {
geocoder.geocode( { 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
result.lat = results[0].geometry.location.lat();
result.lng = results[0].geometry.location.lng();
} else {
result.lat = null;
result.lng = null;
}
// Resolve the Deferred using your result
d.resolve(result);
});
}
// Return the Promise for the Deferred
return d.promise();
}
// Usage
geocode({/*....*/}).done(function(result) {
// This gets called later, asynchronously, with the result
});

Javascript Function Scope Problems [duplicate]

I am working with the google maps API and whenever I return the variable to the initialize function from the codeLatLng function it claims undefined. If I print the variable from the codeLatLng it shows up fine.
var geocoder;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(40.730885,-73.997383);
var addr = codeLatLng();
document.write(addr);
}
function codeLatLng() {
var latlng = new google.maps.LatLng(40.730885,-73.997383);
if (geocoder) {
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
return results[1].formatted_address;
} else {
alert("No results found");
}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
}
prints out undefined
If I do:
var geocoder;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(40.730885,-73.997383);
codeLatLng();
}
function codeLatLng() {
var latlng = new google.maps.LatLng(40.730885,-73.997383);
if (geocoder) {
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
document.write(results[1].formatted_address);
} else {
alert("No results found");
}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
}
prints out New York, NY 10012, USA
You can't return the value from the function, the value doesn't exist yet when the function returns.
The geocode method makes an asynchonous call and uses a callback to handle the result, so you have to do the same in the codeLatLng function:
var geocoder;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(40.730885,-73.997383);
codeLatLng(function(addr){
alert(addr);
});
}
function codeLatLng(callback) {
var latlng = new google.maps.LatLng(40.730885,-73.997383);
if (geocoder) {
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
callback(results[1].formatted_address);
} else {
alert("No results found");
}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
}
You're making an asynchronous request, your codeLatLng() function has finished and returned long before the geocoder is done.
If you need the geocoder data to continue, you'll have to chain your functions together:
function initialize() {
geocoder = new google.maps.Geocoder();
codeLatLng();
}
function codeLatLng() {
var latlng = new google.maps.LatLng(40.730885,-73.997383);
if (geocoder) {
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
initContinued(results[1].formatted_address);
} else {
alert("No results found");
}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
}
function initContinued(addr) {
alert(addr);
}
You can get value using localstorage.
geocoder.geocode({
'address': address,
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
}
localStorage.setItem("endlat", latitude);
localStorage.setItem("endlng", longitude);
});
var end_lat = localStorage.getItem("endlat");
var end_lng = localStorage.getItem("endlng");
But it returns previous value.. Returns current value when we click twice...
pass geocoder as a parameter to the codeLatLng() function.
function codeLatLng(geocoder) {
call it like so in your initialize function:
var addr = codeLatLng(geocoder);
That return is not returning from codeLatLng; it's returning from the anonymous function being passed to geocoder.geocode.
I think you'll need to pass the data using another mechanism e.g. a global variable

How to pass an object to this js function?

Code:
function setMaps() {
var geocoder = new google.maps.Geocoder();
var result = "";
$('.map_canvas').each(function(){
geocoder.geocode( {
'address': $(this).attr('address'),
'region': 'de'
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
result += results[0].geometry.location.lng()+",";
result += results[0].geometry.location.lat();
} else {
result = "Unable to find address: " + status;
}
$(this).gmap({ 'center': result });
});
});
}
This method should show multiple maps on one page.
HTML:
<div class="map_canvas" address="Berlin, Zoo">
</div>
The problem is that $(this).gmap({ 'center': result }); does not work:
Uncaught TypeError: Cannot set property 'position' of undefined
Any idea how to pass the map_canvas object to the callback function?
try this:
function setMaps() {
var geocoder = new google.maps.Geocoder();
var result = "";
$('.map_canvas').each(function(){
var _this = $(this); // <------ here
geocoder.geocode( {
'address': $(this).attr('address'),
'region': 'de'
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
result += results[0].geometry.location.lng()+",";
result += results[0].geometry.location.lat();
} else {
result = "Unable to find address: " + status;
}
_this.gmap({ 'center': result }); // <---- and here
});
});
}

Categories