Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return value from function with an Ajax call [duplicate]

Can someone tell me how to return the value of status as the function's return value.

function checkUser() {
    var request;
    var status = false;

    //create xmlhttprequest object here [called request]

    var stu_id = document.getElementById("stu_id").value;
    var dName = document.getElementById("dName").value;
    var fileName = "check_user.php?dName=" + dName + "&stu_id=" + stu_id;
    request.open("GET", fileName, true);
    request.send(null);

    request.onreadystatechange = function() {
        if (request.readyState == 4) {
            var resp = parseInt(request.responseText, 10);
            if(resp === 1) {
                alert("The display name has already been taken.");
                status = false;
            }
            else if(resp === 2) {
                alert("This student ID has already been registered");
                status = false;
            }
            else if(resp === 0) {
                status = true;
            }
        }
    }
    return status;
}

The above function triggers when you hit submit in a registration form (as must be obvious). The problem is, this form submits irrespective of what the response is, and the alert box sometimes shows nothing [blank], sometimes doesn't show at all. However, if I change the ending status to false manually [i.e. replace status with false], the correct value shows up in the alert box.

P.S. I'm worse than a noob in javascript, so suggestions on generally improving the code is also welcome.

like image 998
Mussnoon Avatar asked Feb 18 '09 19:02

Mussnoon


People also ask

Can we return a value from ajax call?

You can't return "true" until the ajax requests has not finished because it's asynchron as you mentioned. So the function is leaved before the ajax request has finished.

How can a function return a value in ajax?

ajax({ async: true, contentType: 'application/json; charset=utf-8', type: "POST", dataType: 'json', data: JSON. stringify(arrays), url: "MyHandler. ashx", success: function (result) { b = true; }, error: function () { alert('Error occurred'); } });

How do I return a response from ajax?

The A in Ajax stands for asynchronous. That means sending the request (or rather receiving the response) is taken out of the normal execution flow. In your example, $. ajax returns immediately and the next statement, return result; , is executed before the function you passed as success callback was even called.

How do I return data after ajax call success?

You can store your promise, you can pass it around, you can use it as an argument in function calls and you can return it from functions, but when you finally want to use your data that is returned by the AJAX call, you have to do it like this: promise. success(function (data) { alert(data); });


1 Answers

The problem is that onreadystatechange won't fire until... wait for it... the state changes. So when you return status; most of the time status will not have had time to set. What you need to do is return false; always and inside the onreadystatechange determine whether you want to proceed or not. If you do, then you submit the form. In short, take the code that handles the return value and instead run it from within the readystatechange handler. You can do this directly:

request.onreadystatechange = function() {
    if (request.readyState == 4) {
        var resp = parseInt(request.responseText, 10);
        switch (resp) {
        case 0:
            document.getElementById('myform').submit();
            break;
        case 1:
            alert("The display name has already been taken.");
            break;
        case 2:
            alert("This student ID has already been registered");
            break;
        }
    }
}
return false; // always return false initially

or by passing a continuation to the function that makes the asynchronous call:

function checkUser(success, fail) {
    ...
    request.onreadystatechange = function() {
        if (request.readyState == 4) {
            var resp = parseInt(request.responseText, 10);
            switch (resp) {
            case 0:
                success(request.responseText);
            case 1:
                fail("The display name has already been taken.", request.reponseText);
                break;
            case 2:
                fail("This student ID has already been registered", request.reponseText);
                break;
            default:
                fail("Unrecognized resonse: "+resp, request.reponseText);
                break;
            }
        }
    }

In addition to this, before the default return false; you might want to have some sort of indicator that something is going on, perhaps disable the submit field, show a loading circle, etc. Otherwise users might get confused if it is taking a long time to fetch the data.

Further explanation

Alright, so the reason your way didn't work is mostly in this line:

request.onreadystatechange = function() {

What that is doing is saying that when the onreadystatechange of the AJAX request changes, the anonymous function you are defining will run. This code is NOT being executed right away. It is waiting for an event to happen. This is an asynchronous process, so at the end of the function definition javascript will keep going, and if the state has not changed by the time it gets to return status; the variable status will obviously not have had time to set and your script would not work as expected. The solution in this case is to always return false; and then when the event fires (ie, the server responded with the PHP's script output) you can then determine the status and submit the form if everything is a-ok.

like image 176
Paolo Bergantino Avatar answered Nov 12 '22 22:11

Paolo Bergantino