First of all let's agree on a definition of what you call "async": a non-blocking piece of code that will be executed later on when a condition has been fulfilled right ?
By this definition there are some "async" calls in your code alright, navigator.geolocation.getCurrentPosition()
, $.ajax()
, but also .click()
and $()
.
Each of which will call back a provided function that you provide (callback).
In case of getCurrentPosition()
, it receives 3 parameters, 2 of which are callbacks respectively executed upon success / failure (optional), and a configuration object (optional). And you are definitely handling that alright.
But:
- your syntax seem a bit wrong,
getcoordinates()
is not triggered by anything previous to the button click
- either way you are not specifically waiting for
getcoordinates()
to finish before handling the returned value in your .click()
handler
- you shouldn't scope unecessarily your function definitions
- where are
userlat
and userlong
declarations ?
- don't forget that arrays are 0 indexed
TL;DR play around with this:
function getCoordinates(thenCb, errorCb) {
thenCb = thenCb || function () {};
errorCb = errorCb || function () {};
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(thenCb, errorCb, {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
});
} else {
alert('Geolocation is not supported by this browser.');
}
}
$(function () {
$('#go').click(function () {
getCoordinates(function (pos) {
$.ajax({
url: 'dbphp.php',
method: 'POST',
data: {
userlong: pos.coords.latitude,
userlat: pos.coords.longitude
},
success: function (data) {
// do stuff with data...
}
});
}, function (err) {
console.warn('Geolocation error ' + err.code + ': ' + err.message);
});
});
});
For an ES6+ version:
const getCoordinates = (thenCb = () => {}, errorCb = () => {}) => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(thenCb, errorCb, {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
});
} else {
alert('Geolocation is not supported by this browser.');
}
};
$(() => {
$('#go').click(() => {
getCoordinates(({ coords }) => {
const { userlong, userlat } = coords;
$.ajax({
url: 'dbphp.php',
method: 'POST',
data: { userlong, userlat },
success: (data) => {
// do stuff with data...
}
});
}, (err) => {
console.warn(`Geolocation error ${err.code}: ${err.message}`);
});
});
});
Note 1: You might want to refactor this based on your needs and context, avoid setting getCoordinates()
in global scope, etc.
Note 2: It is okay in this case to wait for getCoordinates()
completion on user click because, although "async", the function does return results swiftly. Usually when it takes longer to resolve you might want to a) fire the function previous to the click handler in order to memoize its return value, b) show a loading state to the user.
Regarding the xhr request, note that you are using jQuery.ajax()
and the response data will be available in your success
callback provided as its first argument.
Also, be sure to check out the docs:
- https://developer.mozilla.org/en-US/docs/Web/API/Geolocation
- https://api.jquery.com
If interested, read on how to make use of Promises, to make callback code a lot more digest: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
If still interested, read on how to use async
/ await
to make Promises code a lot more digest: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function