I'm trying to get user's city and country before moving on with my code. It seems as if javascript is not executed in the order I need.
$(document).ready(function() {
var country, city = '';
function geoData() {
$.getJSON('=?', function (data) {
console.log('step 1');
country = data.country;
city = data.city;
console.log('step 2');
});
};
geoData();
console.log('step 3');
/* rest of the code */
});
I want the code to be executed as:
step 1
step 2
step 3
However when I run the script I get:
step 3
step 1
step 2
Why is the code running in an asynchronous way? Any suggestions how I can fix it?
Thanks.
I'm trying to get user's city and country before moving on with my code. It seems as if javascript is not executed in the order I need.
$(document).ready(function() {
var country, city = '';
function geoData() {
$.getJSON('http://ipinfo.io/json?callback=?', function (data) {
console.log('step 1');
country = data.country;
city = data.city;
console.log('step 2');
});
};
geoData();
console.log('step 3');
/* rest of the code */
});
I want the code to be executed as:
step 1
step 2
step 3
However when I run the script I get:
step 3
step 1
step 2
Why is the code running in an asynchronous way? Any suggestions how I can fix it?
Thanks.
Share Improve this question edited Oct 3, 2017 at 7:12 Rory McCrossan 338k41 gold badges320 silver badges351 bronze badges asked Jun 30, 2015 at 15:03 tamirostamiros 3391 gold badge4 silver badges10 bronze badges 1- 2 Wait for the load to finish, and then run step 3. – jackJoe Commented Jun 30, 2015 at 15:04
2 Answers
Reset to default 8AJAX requests are asynchronous - it's what the first A stands for. If you have logic that depends on the data returned by the request, it needs to be placed within the callback function. Try this:
var country, city = '';
function geoData() {
$.getJSON('http://ipinfo.io/json?callback=?', function (data) {
console.log('step 1');
country = data.country;
city = data.city;
console.log('step 2');
step3();
});
};
function step3() {
console.log('step 3');
}
geoData();
An alternative is to use a promise, although the logic flow is roughly equivalent:
var country, city = '';
function geoData() {
return $.getJSON('http://ipinfo.io/json?callback=?', function (data) {
console.log('step 1');
country = data.country;
city = data.city;
console.log('step 2');
});
};
var deferred = geoData();
$.when(deferred).done(function() {
console.log('step 3');
});
Use jQuery promises to get your desired result, like so:
var geoDataRequest = function () {
var deferred = $.Deferred();
$.getJSON('http://ipinfo.io/json?callback=?', function (data) {
deferred.resolve(data);
});
return deferred.promise();
};
var somefunction = function () {
// This will return a promise
var getGeoData = geoDataRequest ();
// The appropriate function will be called based on if the promise is resolved or rejected through the success and error functions in the AJAX request
getGeoData.then(
// Done response
function (result) {
alert("Success! ");
// Enter logic here for step 2 and 3
},
// Fail response
function (xhr, status, errorThrown) {
// Handle errors here...
}
);
};
somefunction();
In addition, you can now use your geoDataRequest
whenever you like, and handle the results differently if you like!