48

I have a js function , after doing some business logic, the javascript function should return some result to another variable.Sample code below

var response="";
function doSomething() {  
    $.ajax({
        url:'action.php',
        type: "POST",
        data: dataString,
        success: function (txtBack) { 
            if(txtBack==1) {
                status=1;
            }
    });
    return status;     
}

Here i want to use like

response=doSomething();

I want to assign a return value "status" "var response".But the result is 'undefined'.

GEOCHET
  • 21,119
  • 15
  • 74
  • 98
Ra.
  • 935
  • 4
  • 18
  • 30
  • Already got the correct wording in your title: *return value*. But you are not using `return` in your function ;) – Felix Kling Oct 15 '10 at 10:33
  • Note that usually you don't need to initialize new variables with values if those values are falsy (which an empty string is). You can just write: var response; The value of response will be set to the undefined value in this case (which is also a falsy value). Then later, when you want to check if the value has been set, you can just check if it is falsy or not... – Šime Vidas Oct 15 '10 at 10:45
  • @Felix: i have a ajax call inside the function, it is returning "undefined". any idea? Thanks – Ra. Oct 15 '10 at 11:14
  • 2
    Search here on SO about this issue. This is normal. You cannot return a value form an Ajax call, because it is executed asynchronously, i.e. the `return` statement is executed *before* the Ajax call finished. You can solve this using callbacks... – Felix Kling Oct 15 '10 at 11:21
  • @Felix: Hi, i made a little change in the code, after success condition, i just include "async :false".... now the code is working fine as expected :) – Ra. Oct 19 '10 at 07:55
  • @Ra: But keep in mind that `async: false` is bad. Depending on how long the Ajax call takes, it can freeze the browser. And you loose imho the most important feature of an Ajax call. – Felix Kling Oct 19 '10 at 08:00

5 Answers5

82

Or just...

var response = (function() {
    var a;
    // calculate a
    return a;
})();  

In this case, the response variable receives the return value of the function. The function executes immediately.

You can use this construct if you want to populate a variable with a value that needs to be calculated. Note that all calculation happens inside the anonymous function, so you don't pollute the global namespace.

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
21

AJAX requests are asynchronous. Your doSomething function is being exectued, the AJAX request is being made but it happens asynchronously; so the remainder of doSomething is executed and the value of status is undefined when it is returned.

Effectively, your code works as follows:

function doSomething(someargums) {
     return status;
}

var response = doSomething();

And then some time later, your AJAX request is completing; but it's already too late

You need to alter your code, and populate the "response" variable in the "success" callback of your AJAX request. You're going to have to delay using the response until the AJAX call has completed.

Where you previously may have had

var response = doSomething();

alert(response);

You should do:

function doSomething() {  
    $.ajax({
           url:'action.php',
           type: "POST",
           data: dataString,
           success: function (txtBack) { 
            alert(txtBack);
           })
    }); 
};
Alexis Tyler
  • 1,394
  • 6
  • 30
  • 48
Matt
  • 74,352
  • 26
  • 153
  • 180
9

You could simply return a value from the function:

var response = 0;

function doSomething() {
    // some code
    return 10;
}
response = doSomething();
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Its working... but i have ajax call inside, in thats time the result is 'undefined'. Any idea? Please look at the modified sample code. – Ra. Oct 15 '10 at 11:12
2

The only way to retrieve the correct value in your context is to run $.ajax() function synchronously (what actually contradicts to main AJAX idea). There is the special configuration attribute async you should set to false. In that case the main scope which actually contains $.ajax() function call is paused until the synchronous function is done, so, the return is called only after $.ajax().

function doSomething() {
    var status = 0;
    $.ajax({
        url: 'action.php',
        type: 'POST',
        data: dataString,
        async: false,
        success: function (txtBack) {
            if (txtBack == 1)
                status = 1;
        }
    });

    return status;
}

var response = doSomething();
impulsgraw
  • 887
  • 3
  • 13
  • 34
2

The result is undefined since $.ajax runs an asynchronous operation. Meaning that return status gets executed before the $.ajax operation finishes with the request.

You may use Promise to have a syntax which feels synchronous.

function doSomething() { 
    return new Promise((resolve, reject) => {
        $.ajax({
            url:'action.php',
            type: "POST",
            data: dataString,
            success: function (txtBack) { 
                if(txtBack==1) {
                    resolve(1);
                } else {
                    resolve(0);
                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
                reject(textStatus);
            }
        });
    });
}

You can call the promise like this

doSomething.then(function (result) {
    console.log(result);
}).catch(function (error) {
    console.error(error);
});

or this

(async () => {
    try {
        let result = await doSomething();
        console.log(result);
    } catch (error) {
        console.error(error);
    }
})();
Aley
  • 8,540
  • 7
  • 43
  • 56