0

I have a small piece of js that pull some data from via ajax.

solarSystem = "test";

$.getJSON( "ajax/getLocation.php", function( data ) {
      var items = [];
      $.each( data, function( key, val ) {          
            solarSystem = val;          
      });
});

alert(solarSystem);

val is being set but its not outputting to the alert if i put the alert in that function it works. I assume its something to do with scope but im new to js if anyone can point me in the right direction it would be much apreciated.

Louise McMahon
  • 1,655
  • 3
  • 15
  • 21
  • 3
    It's not scope, it's to do with asynchronous functions. The `alert` is running before the `solarSystem = val;`. In the kindest possible way, read a book on JS, it's the quickest way to understand this. – Joe May 11 '14 at 22:10
  • 1
    While the getJSON function captures the solarSystem variable, the alert box will always run before the AJAX request returns. You could put the alert inside the getJSON callback function at the end and it would then work as you expect it to. –  May 11 '14 at 22:11
  • Welcome to the wonderful world of **async**! You can't do that. – SLaks May 11 '14 at 22:11
  • @jqueryrocks the alert will *always* run before the request returns. – Joe May 11 '14 at 22:12
  • alert your variable in success handler instead – Rahil Wazir May 11 '14 at 22:12
  • Answers is given in the following: [http://stackoverflow.com/questions/1739800/variables-set-during-getjson-function-only-accessible-within-function][1] – pascalvgemert May 11 '14 at 22:13
  • @Joe made the edit, thanks –  May 11 '14 at 22:14

2 Answers2

2

While JavaScript is single-threaded, it can perform tasks asynchronously, i.e. function calls do not necessarily complete before the next line of code. AJAX (asynchronous JavaScript and XML) calls do just that. For example,

console.log("starting")
$.getJSON("path/to/resource", function (data) {
    console.log("data retrieved")
})
console.log("finished")

The above code will most likely print starting and finished before it prints data retrieved. This is because $.getJSON is asynchronous. It requests a resource on a server somewhere, waits for a response, then calls the anonymous function provided as a callback, i.e. the function (data) { /* etc */ } part.

In your case, the callback function is running after alert, even though it is written above it in your code. If you want to alert(solarSystem), you'll need to place that inside of your $.getJSON call to ensure it is processed correctly:

solarSystem = "test"

$.getJSON("ajax/getLocation.php", function (data) {
    var items = []
    $.each(data, function (key, val) {          
        solarSystem = val
    })
    alert(solarSystem)
})
royhowie
  • 11,075
  • 14
  • 50
  • 67
-3

Anything inside the $.getJSON cannot access anything outside without some changes to your code. You need what is a called a callback function, and the problem is due to variable scoping.

solarSystem = "test";
function setSolarSystem(newSystem){
    solarSystem = newSystem;
    alert(solarSystem);
}
$.getJSON( "ajax/getLocation.php", function( data ) {
      var items = [];
      $.each( data, function( key, val ) {          
            setSolarSystem(val);          
      });
});
BenFuller
  • 16
  • 1