How to return value from nested asynchronous function in JavaScript?

Hi,

I use ajax calls to return data from my db. All good.  But how do I return the value from the ajax call when it is nested inside another function:

I want to return fraudalert but below does not work since the callback function from the ajax is executed asynchronously, while the return fromFraudAlert() will happen immediately after the transaction is started.

function FraudAlert(){

    var fraudalert = 'false';
    var ChequeNumber1 = $("#TextBoxChequeNo1").val();
    var ChequeNumber2 = $("#TextBoxChequeNo2").val();
    var ChequeNumber3 = $("#TextBoxChequeNo3").val();
    var frauddata = [];
    frauddata.push(ChequeNumber1 + ':' + ChequeNumber2 + ':' + ChequeNumber3);
    $.ajax({
        type: "POST",
        url: "chequedeposit.asmx/FraudAlert",
        data: '{frauddata: ' + JSON.stringify(frauddata) + '}',
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (data) {
            
            var fraudstatus = data.d;
            
            if (fraudstatus == 'ok') {
                //hiddenfield necessary?
                $("#ButtonDeposit").prop("disabled", false);
                $("#LabelMismatchCheque1").text('');
                $("#LabelDepositInfo").text('');
                fraudalert = 'false';
                $("#HiddenFieldFraudAlert").val('false');
                
            } else {
                alert("Error: " + fraudstatus);
                $("#ButtonDeposit").prop("disabled", true);
                $("#LabelMismatchCheque1").text('Fraud Alert');
                $("#LabelDepositInfo").text(fraudstatus);
                $("#HiddenFieldFraudAlert").val('true');
                fraudalert = 'true';
              
            }

        },
        error: function (result) {

            alert("Fraud Error");
            
        }

    });
//this always returns the initial value, false.  I want it to return the value from the success function
    return fraudalert;
}

Open in new window


Any help is appreciated
vstackAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

leakim971PluritechnicianCommented:
You currently have something like this :
function foo() {
     // 1 - do this
     // 2 - do that
     // 3 -  blablabla
     // 4 - blablabla
     var fA = fraudalert(); // this is what you currently have.
     // 5 - do this with fA
     // 6 - do that
     // 7 - blablabla
}

Open in new window


now go to :

function foo() {
     // 1 - do this
     // 2 - do that
     // 3 - blablabla
     // 4 - blablabla
     fraudalert(foo_after);
}

function foo_after(fA) {
     // 5 - do this with fA
     // 6 - do that
     // 7 - blablabla
}

and FraudAlert :

function FraudAlert(callback) { // we pass the function to be called once the ajax call is successfully done
    var cb = callback;

    var ChequeNumber1 = $("#TextBoxChequeNo1").val();
    var ChequeNumber2 = $("#TextBoxChequeNo2").val();
    var ChequeNumber3 = $("#TextBoxChequeNo3").val();
    var frauddata = [];
    frauddata.push(ChequeNumber1 + ':' + ChequeNumber2 + ':' + ChequeNumber3);
    $.ajax({
        type: "POST",
        url: "chequedeposit.asmx/FraudAlert",
        data: '{frauddata: ' + JSON.stringify(frauddata) + '}',
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (data) {
            
            var fraudstatus = data.d;
            
            if (fraudstatus == 'ok') {
                //hiddenfield necessary?
                $("#ButtonDeposit").prop("disabled", false);
                $("#LabelMismatchCheque1").text('');
                $("#LabelDepositInfo").text('');
                $("#HiddenFieldFraudAlert").val('false');
                cb('false'); // SEE HERE
                
            } else {
                alert("Error: " + fraudstatus);
                $("#ButtonDeposit").prop("disabled", true);
                $("#LabelMismatchCheque1").text('Fraud Alert');
                $("#LabelDepositInfo").text(fraudstatus);
                $("#HiddenFieldFraudAlert").val('true');
                cb('true'); // SEE HERE
              
            }

        },
        error: function (result) {

            alert("Fraud Error");
            
        }

    });
}

Open in new window

0
Steve BinkCommented:
If your app depends on the return from FraudAlert() before continuing, then you should make that AJAX call synchronous.
0
leakim971PluritechnicianCommented:
@Steve Bink, please read this :
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests#Synchronous_request
and :
http://api.jquery.com/jquery.ajax/
As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done() or the deprecated jqXHR.success().

Open in new window

0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

Steve BinkCommented:
@leakim971: Understood, but the OP's pattern is not using the Deferred API.  I still maintain that if the application needs to wait on a response, it needs to implement a synchronous call..  that's the point of synchronous vs asynchronous.
0
leakim971PluritechnicianCommented:
<< How to return value from nested asynchronous function in JavaScript? >>
That make me think the author know synchronous ajax call is deprecated
0
Steve BinkCommented:
To be clear, it is not the synchronous call that is deprecated.  It is the use of the Deferred object's API with a synchronous call which is deprecated.  And that only makes sense - if you have a blocking call, you do not need to trap an event when the call completes.  The "handler" will be the line of code after the call.

Also, the $.ajax() call defaults to an asynchronous call.  If no other config is done, then every call will be asynchronous.  That also makes sense - synchronous calls are needed only in specific situations.  My assertion is that this is one of them.  If the script requires the return from FraudAlert() before it can continue, then it needs to wait on that return.  I.e., it needs a synchronous call that blocks execution until is complete.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
vstackAuthor Commented:
Thanks to both.  I implemented the solution from leakim971. Thanks to Steve Bink, I have a much clearee idea about how all this works.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JSON

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.