5

I'm trying to change the value of a variable in a closure:

var myVariable;
$.ajax({
    //stuff....
    success:function(data) {
        myVariable = data;
    }
});

This does not work because myVariable is not visible to the closure. How do I change this code so that the value of myVariable changes?

5
  • 1
    That's not true. By definition, if it's global, it's accessible in all scopes. Of course, if there is a local variable called myVariable, then it will be modified instead of the global version. If it's truly global, you can do window.myVariable to access it. Commented Nov 21, 2012 at 6:19
  • 1
    Your example doesn't show why it wouldn't be visible in the scope of the success callback. The only thing that would hide it would be that there is a variable with the same name in a closer scope that shadows it. Commented Nov 21, 2012 at 6:19
  • Hmm, I think the variable isn't getting changed because ajax is no syncrhonouse. Not sure how to make it syncrhronous though Commented Nov 21, 2012 at 6:23
  • 1
    @user1811367: Don't. Learn how to work with callbacks. Commented Nov 21, 2012 at 6:29
  • myVariable is updated (check it out in Firebug to see). But not when you think it should be. Check out my answer. Commented Nov 21, 2012 at 6:35

2 Answers 2

13

Contrary to your belief, your code works. But seeing what you're trying to do and reading between the lines I'm guessing you're trying to do this:

var myVariable;
$.ajax({
    //stuff....
    success:function(data) {
        myVariable = data;
    }
});
alert(myVariable); // at this point myVariable is undefined!!

If so, you need to learn about asynchronous functions.

Basically, the $.ajax() function returns before actually submitting the ajax request. It will do the ajax request later when the browser is not busy executing javascript. Which means that the assignment will not have happened yet when you try to alert the value of myVariable.

Read my response here for more detail: JS global variable not being set on first iteration

The only good solution is to change the way you think about coding. (There is an arguably bad solution that involves turning the ajax call to synchronous but lets not get in to that, you can google it if you want or read the manual). Instead of doing this:

var myVariable;
$.ajax({
    //stuff....
    success:function(data) {
        myVariable = data;
    }
});
/*
 * Do lots of stuff with the returned value
 * of the myVariable variable
 *
 */

you now need to write it like this:

var myVariable;
$.ajax({
    //stuff....
    success:function(data) {
        myVariable = data;
        /*
         * Do lots of stuff with the returned value
         * of the myVariable variable
         *
         */
    }
});

Basically moving any and all code that you would have written after the ajax call into the success callback. This takes getting used to (judging from how many variants of this question exist on the internet). But once you're used to it it becomes second nature.

There is a name for this style of programming. It is variously known as: "event driven programming" or "continuation-passing style" or "evented programming". You can google the various terms if you want to know more.

Sign up to request clarification or add additional context in comments.

2 Comments

This likely gets at the heart of the problem, though it's hard to tell given the explanation.
@tjameson: In my experience, whenever someone tries to assign the result of a callback to an enclosed variable then it most likely is the problem. Answer questions on SO long enough and you sort of see patterns to the questions.
3

If that code is in the global scope, myVariable is visible to the inner function. If you're worried about it being shadowed by a local variable, explicitly access it as a property of the global:

var myVariable;
$.ajax({
    //stuff....
    success:function(data) {
        window.myVariable = data;
    }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.