-1

I want to use some variables outside the jquery function, but I am failing to make them global. I have followed the advice to first 'var' them and then assign them, but the last log() returns undefined.

var lat,lon;
$.get('ip.json',function(data) {
    var loc=data['loc'];
    lat=loc.split(',')[0];
    lon=loc.split(',')[1];
    },'json');
console.log(lat,lon);

UPDATE Here is the full code

var lat,lon;
$.get('ip.json',function(data) {
    console.log(data);
    var city=data['city'];
    var loc=data['loc'];
    lat=loc.split(',')[0];
    lon=loc.split(',')[1];
    $('body').append(' '+city+' '+lat+' '+lon);
    },'json');
console.log(lat,lon);
$.get('apiurl?lat='+lat+'&lon='+lon+'&callback=test',function(data) {},'json'),
Dirk N
  • 717
  • 3
  • 9
  • 23
  • 4
    `$.get()` is async. The `console.log()` line executes before the ajax callback function. – Jason P Oct 17 '13 at 13:15
  • Use `$.ajax()` and make it sync with `async: false` – Brewal Oct 17 '13 at 13:16
  • 1
    @Brewal I've said it before, I'll say it again, `async: false` is never the answer. – Rory McCrossan Oct 17 '13 at 13:18
  • Indeed but this is the only way to use this vars as global. If we really don't want to use it then the answer is "it's not possible, rethink your developpement" – Brewal Oct 17 '13 at 13:19
  • Ok I am using 1.9 so async=false not an option. Is there an easy way to rewrite this? I read the other post but not clear enough. – Dirk N Oct 17 '13 at 13:22
  • The question becomes *when is "later"* in your context? At what point do you want to log the values? When they change? After 5 seconds? Every 5 seconds? Other? – iCollect.it Ltd Oct 17 '13 at 13:25
  • 1
    @Brewal you can easily set vars globally in a callback, but if you follow the async pattern properly you don't need to. The last thing anyone should be doing is littering global variables. – Rory McCrossan Oct 17 '13 at 13:25
  • 1
    @DirkNachbar Could you post your full JS code. I'm not seeing how the answers below don't solve your problem. – Rory McCrossan Oct 17 '13 at 13:26

5 Answers5

1

Given your new code, a simple solution would be to nest the calls:

$.get('ip.json', function (data) {
    console.log(data);
    var city = data['city'];
    var loc = data['loc'];
    var lat = loc.split(',')[0];
    var lon = loc.split(',')[1];
    $('body').append(' ' + city + ' ' + lat + ' ' + lon);
    $.get('apiurl?lat=' + lat + '&lon=' + lon + '&callback=test', function (data) {
        //handle second response here
        console.log(lat, lon);
    }, 'json');
}, 'json');
Jason P
  • 26,984
  • 3
  • 31
  • 45
1

Given your updated code you need to hang all logic dependant on the result of the AJAX call off the handler:

var lat, lon;
$.get('ip.json', function(data) {
    console.log(data);
    var city = data['city'];
    var loc = data['loc'];
    lat = loc.split(',')[0];
    lon = loc.split(',')[1];
    $('body').append(city + ' ' + lat + ' ' + lon);

    // at this point you now have the data for your second AJAX call:
    console.log(lat,lon);
    $.get('apiurl?lat=' + lat + '&lon=' + lon + '&callback=test', function(data){       
        // do something 
    },'json'),
},'json');
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
0

The issue is you are issuing an asynchronous call which returns AFTER the call to console.log. You need to include console.log in your callback for it to work properly.

var lat,lon;
$.get('ip.json',function(data) {
    var loc=data['loc'];
    lat=loc.split(',')[0];
    lon=loc.split(',')[1];
    console.log(lat,lon);
    },'json');
Mister Epic
  • 16,295
  • 13
  • 76
  • 147
  • 1
    I need it outside/global/later not inside – Dirk N Oct 17 '13 at 13:17
  • 2
    You're going to have to review the asynchronous programming model. You need to leverage callbacks like above, and then order your calls appropriately. You can still assign global variables, but you need to ensure that the variables have values assigned to them first! – Mister Epic Oct 17 '13 at 13:19
  • 1
    You can't specify "later" per se using this method. What you could do, however, is set up another function that triggers your console.log when you've received a successful return, but "later" in a script does not equal "later" in time, when dealing with asynchronous requests. – Jason M. Batchelor Oct 17 '13 at 13:20
  • As noted above, you can make `$.get` synchronous, which would solve your problem, but you really should understand how the asynchronous model works. – Mister Epic Oct 17 '13 at 13:21
  • Why is this answer downvoted? It's correct. – Rory McCrossan Oct 17 '13 at 13:27
0

further to what the above guys are saying i believe you can make a AJAx call asynchronous. Have a look here How to make JQuery-AJAX request synchronous

Community
  • 1
  • 1
Millard
  • 1,157
  • 1
  • 9
  • 19
  • 4
    But whatever you do... avoid actually using Ajax in *synchronous* mode. This leads to the dark-side. Learn to work with async operations. – iCollect.it Ltd Oct 17 '13 at 13:21
  • 2
    You /can/ make AJAX calls synchronous, but remember that will also become a blocking call... no other script will execute until that call returns, so you're at the mercy of the remote server + latency to make sure that your script proceeds with any other duties it needs to perform. – Jason M. Batchelor Oct 17 '13 at 13:22
  • I should have added that thanks. – Millard Oct 17 '13 at 14:53
0

You can use ajax asyc call

$.ajax({
    async: "false",
        type: "GET",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        url: "uri",
        success: function(data) {
            var loc=data['loc'];
            lat=loc.split(',')[0];
        lon=loc.split(',')[1];
        }
    });
console.log(lat,lon);
Andy
  • 332
  • 1
  • 13
  • 3
    I think you meant sync (synchronous), not async (asynchronous), but I strongly recommend you *do not use Ajax synchronous mode* but instead learn to work with async operations. – iCollect.it Ltd Oct 17 '13 at 13:23
  • You should never set the `async` property to `false`. Learn to use callbacks and promise objects... – War10ck Oct 17 '13 at 13:38