-4

This is the function:

function verificaProva(aluno,prova){
        // define o retorno padrao
        var res = 0;

        // busca informação do servidor
        $.ajax({
            url : "funcoes.php",
            type : 'post',
            dataType : "json",
            data : {acao: "verificaProva", id_aluno: aluno, id_prova: prova},
            success : function(retorno){
                if (retorno.status == "fez"){
                    res = 1;
                    alert("fez");
                } 
            },
            error : function(jqXHR, textStatus, errorThrown){
                alert(textStatus+"\n"+errorThrown);
            }
        });
        return res;
    }

If the condition of the ajax return is true, the function displays an alert and arrow the variable to "1".

What happens is that the alert is being issued, but the variable does not change, why?

Walter Gandarella
  • 107
  • 2
  • 4
  • 13
  • 1
    Search: http://stackoverflow.com/search?q=can%27t+return+from+ajax It seems this question is asked several time a day. –  Aug 10 '13 at 20:06

4 Answers4

1

An Ajax call is made asynchronously, meaning that the function you pass to the success property will only be called once the request is made, after a while.

So your res variable will only be set after the response from the server is received.

1 - You have 2 choices here, put the async property of your ajax options to false :

$.ajax({
        //async set to false
        async: false,
        url : "funcoes.php",
        type : 'post',
        dataType : "json",
        data : {acao: "verificaProva", id_aluno: aluno, id_prova: prova},
        success : function(retorno){
            if (retorno.status == "fez"){
                res = 1;
                alert("fez");
            } 
        },
        error : function(jqXHR, textStatus, errorThrown){
            alert(textStatus+"\n"+errorThrown);
        }
    });

2 - You can pass a callback function to your function, which will be called in the success function :

function verificaProva(aluno,prova,callback){
    // busca informação do servidor
    $.ajax({
        url : "funcoes.php",
        type : 'post',
        dataType : "json",
        data : {acao: "verificaProva", id_aluno: aluno, id_prova: prova},
        success : function(retorno){
            if (retorno.status == "fez"){
                //Callback method called
                callback();
                alert("fez");
            } 
        },
        error : function(jqXHR, textStatus, errorThrown){
            alert(textStatus+"\n"+errorThrown);
        }
    });
}

I would prefer option 2 as it will not make the browser hangs up.

alexbchr
  • 603
  • 4
  • 14
  • I just do not understand how I implement the callback in this example – Walter Gandarella Aug 10 '13 at 20:28
  • You simply call your *verificaProva* function using : `verificaProva(aluno, prova, function() { /*Code goes here*/ });`. With the code supplied in my answer, your function that you pass as a parameter to the *verificaProva* function will be called on the line with the code *callback();* – alexbchr Aug 10 '13 at 20:33
  • There aren't only **2** options. You could also use `return $.ajax({...` in the function. And then call it like `verificaProva("a", "b").done(function (retorno) { /* DO STUFF */ });` – Ian Aug 10 '13 at 20:48
  • Forgot that way but you are right and it is somewhat better, as the *success* property is deprecated [see documentation](http://api.jquery.com/jQuery.ajax/). Why I prefered passing a callback method is because that way the validation made by `if (retorno.status == "fez")` is made by the function itself and not by the caller of the function. – alexbchr Aug 10 '13 at 21:00
1

As stated in the comments on the OP, possible duplicate of How do I return the response from an asynchronous call?.

Quick answer

The callback of the ajax function is executed asynchronously. When the function success is executed, the function verificaProva has already returned. What's basically going on is:

var  res = 0 is executed

$.ajax({...}) is executed and a request is sent to the server

return res is executed, where res is still equal to 0

... some times later ...

when the server responds to the ajax request the callback (success) is executed, and res is set equal to 1. As I said, however, the original function has already returned so it has no effect.

You might want to read a bit about what it means to be executed asynchronously, and also eventually closures.

Hope it helped.

Community
  • 1
  • 1
Aegis
  • 1,749
  • 11
  • 12
0

Your ajax call is ASYNCHRONOUS. That what the "A" stands for in Ajax. As such, the value of res is not filled in by the success handler until some time LATER, long after the $.ajax() function has returned. Thus, you can't return your results value from the ajax function.

Instead, you have to change the way you code and the ONLY code that can use the return value from the asynchronous call is the code that resides in the success handler function or is called from the success handler. You can't write synchronous code with asynchronous operations. You must write the code to work with asynchronous completion functions.

So, in your specific code, you could pass in a callback function and only in that callback function would the value of res be known:

function verificaProva(aluno,prova, cb){

    // busca informação do servidor
    $.ajax({
        url : "funcoes.php",
        type : 'post',
        dataType : "json",
        data : {acao: "verificaProva", id_aluno: aluno, id_prova: prova},
        success : function(retorno){
            if (retorno.status == "fez"){
                // call the callback function with the status
                cb(1);
                alert("fez");
            } 
        },
        error : function(jqXHR, textStatus, errorThrown){
            alert(textStatus+"\n"+errorThrown);
            // call the callback function with the status
            cb(0);
        }
    });
}
jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

It's because AJAX calls are asynchronous by default. So your variable "res" is return before the ajax call ending. So its value is 0.

You have two solutions :

  • make a callback in your success to execute the portion of code which need res's value.
  • make the ajax call synchronous by setting async: false (bad idea in most common cases).
Nagendra Rao
  • 7,016
  • 5
  • 54
  • 92
Dragu
  • 3,242
  • 2
  • 16
  • 15