Mailing List Archive


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [tlug] Variable scope in Javascript driving me nuts



Normally you wouldn't want to, but if you did, I think you can make it synchronous by using $.ajax instead of $.post

http://api.jquery.com/jQuery.ajax/


 -Jdbk

On Thu, Aug 26, 2010 at 1:37 PM, Philipp Wollermann <philipp@example.com> wrote:
Hi Dave,

your code looks like you're thinking of AJAX as a synchronous / blocking way of programming, however it is not. :)
I'll try to explain, why I think the code doesn't work the way you want it to (however, I'm far from being an expert - maybe my way isn't the best way either).

On Aug 26, 2010, at 18:29 , Dave M G wrote:

> my function()
> {
>    var valid = false;

You declare valid as a local variable in the scope of your function.

>    string = JSON.stringify(data);

(BTW: You want to make that a "var string = ...", because else "string" is a global variable, which is unneeded here.)

>    $.post('jsonhandler.php', {JSON: string}, checkResult, "json");

Now you're telling jQuery to asynchronously POST the JSON data and call the function checkResult *when the request is finished*!
However, your outside function just continues immediately after this line. It doesn't wait for any result!
I don't even know why it works at all: You define the function "checkResult" after the function call where you use it..

>    function checkResult(jsonDataReceived)
>    {
>       valid = jsonDataReceived.valid;
>       console.log ("jsonDataReceived.valid = " + jsonDataReceived.valid);
>       console.log ("valid inside checkResult = " + valid);
>    }

This function gets executed in a new context. The variable "valid" is simply not declared here, so it's like creating a new global variable.

>    console.log ("valid OUTSIDE checkResult = " + valid);
>    return valid;

This code gets executed immediately, before your "checkResult" function runs! (Because the actual POST request will take some time)
So you're accessing the local variable "valid" before your "checkResult" had the chance to modify it, so it will always return false.

I don't think, that it's possible to have a "post a query, wait for the result, then return something"-logic (synchronous / blocking).

It's usual style to do it the "post a query, let the rest of the app continue, and when the request is finished, get back to it using a handler-function and deal with the data"-way (asynchronous / non-blocking).

You probably want to do it like this:

function my_function() {
 var string = JSON.stringify(data);

 $.post('jsonhandler.php', {JSON: string},
   function (data) {
     var valid = jsonDataReceived.valid;
     console.log ("jsonDataReceived.valid = " + jsonDataReceived.valid);
     console.log ("valid inside checkResult = " + valid);
     // Do something with your data now. :)
   }, 'json');
}

You might be wondering why I'm declaring the handler-function "inline" here. That's actually typical for _javascript_ and called an "anonymous function". You'll find it in nearly all examples, like here: http://api.jquery.com/jQuery.post/ :)

I hope it helps!

Best regards,
Philipp


--
To unsubscribe from this mailing list,
please see the instructions at http://lists.tlug.jp/list.html

The TLUG mailing list is hosted by the award-winning Internet provider
ASAHI Net.
Visit ASAHI Net's English-language Web page: http://asahi-net.jp/en/


Home | Main Index | Thread Index

Home Page Mailing List Linux and Japan TLUG Members Links