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.

7
  • 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. Commented May 11, 2014 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. Commented May 11, 2014 at 22:11
  • Welcome to the wonderful world of async! You can't do that. Commented May 11, 2014 at 22:11
  • @jqueryrocks the alert will always run before the request returns. Commented May 11, 2014 at 22:12
  • alert your variable in success handler instead Commented May 11, 2014 at 22:12

2 Answers 2

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)
})
Sign up to request clarification or add additional context in comments.

Comments

-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);          
      });
});

2 Comments

No. It doesn't create a new thread. JS is single-threaded, that's a very misleading thing to say!
And no, it's not due to scoping either.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.