19

I have reviewed a lot of answers to this type of question and now I am confused as to the best way. Given the latest jquery, I am wanting to

  1. Call an ajax function
  2. do ajax processing (success or error) // works fine
  3. on success or error return the status to the calling function for further processing

in the calling function (doAjax), how do I wait for a callback then complete the processing for success or error (in this case its on success clear a form, on error keep it as is)

Thx for any advice,

Art [EDIT] There was a typo as you guys spotted, call should have been doAnAjax not doAjax

$(function () {
    doAnAjax(Url, data, function (myRtn) {
        if (myRtn == "success") {
            resetForm($('#myForm'));
            resetForm($('form[name=addChlGrp]'));
        } else {
            $('.rtnMsg').html("Opps! Ajax Error");
        }
    });
});

function doAnAjax(newUrl, data) {
    $.ajax({
        url: newUrl,
        async: true,
        dataType: 'html',
        beforeSend: function () {
            $('.rtnMsg').html("<img src=_cssStyleImg_-A-loading.gif>");
        },
        type: "GET",
        data: data,
        cache: false,
        success: function (data, textStatus, xhr) {
            $('.rtnMsg').html(data);
            myRtnA = "Success"
            return myRtnA;
        },
        error: function (xhr, textStatus, errorThrown) {
            $('.rtnMsg').html("opps: " + textStatus + " : " + errorThrown);
            myRtnA = "Error"
            return myRtnA;
        }
    });
}
Arturs
  • 1,258
  • 5
  • 21
  • 28
art vanderlay
  • 2,341
  • 4
  • 35
  • 64
  • 2
    The best way is to use callbacks. – Felix Kling Jul 20 '12 at 09:04
  • possible duplicate of [Return Value from inside of $.ajax() function](http://stackoverflow.com/questions/8187201/return-value-from-inside-of-ajax-function) – Felix Kling Jul 20 '12 at 09:06
  • @FelixKling while I agree with this, in certain situations synchronous behaviour is preferred. But as I explain in my answer, while the jQuery ajax function does allow you the ability to perform synchronous calls, it is somewhat misleaduing since it isn't really an ajax call anymore. – Jon Taylor Jul 20 '12 at 09:21
  • @Jon: There *might* be use cases, but that does not change the fact that this is a duplicate of all the million other questions about this topic ;) This has already been discussed many times... – Felix Kling Jul 20 '12 at 09:26
  • @FelixKling I wasn;t disputing that, my page had not refreshed as I went to get coffee so hadn't seen your second comment when I made mine :). – Jon Taylor Jul 20 '12 at 09:28
  • @FelixKling, that was one of the posts I read, I misunderstood using the `callBack` as the returning object, I thought that was a reference to the inbound parameter to the ajax function, not the return. thx Art – art vanderlay Jul 20 '12 at 10:45

4 Answers4

18

You've got to use a callback function. Try this below:

$(function() {

   // I think doAjax should doAnAjax()
   // here you're passing callback
   // but you're not using it doAnAjax()

    doAnAjax(Url, data, function(myRtn) {
        if (myRtnV == "success") {
            resetForm($('#myForm'));
            resetForm($('form[name=addChlGrp]'));
        } else {
            $('.rtnMsg').html("Opps! Ajax Error");
        }
    });
});

// pass callback as third parameter to doAnAjax()

function doAnAjax(newUrl, data, callBack) {
    $.ajax({
        url: newUrl,
        async: true,
        dataType: 'html',
        beforeSend: function() {
            $('.rtnMsg').html("<img src=_cssStyleImg_-A-loading.gif>");
        },
        type: "GET",
        data: data,
        cache: false,
        success: function(data, textStatus, xhr) {
            $('.rtnMsg').html(data);
            myRtnA = "Success"
            return callBack( myRtnA );  // return callBack() with myRtna
        },
        error: function(xhr, textStatus, errorThrown) {
            $('.rtnMsg').html("opps: " + textStatus + " : " + errorThrown);
            myRtnA = "Error"
            return callBack ( myRtnA ); // return callBack() with myRtna
        }
    });
Kevin
  • 99
  • 1
  • 12
thecodeparadox
  • 86,271
  • 21
  • 138
  • 164
  • 1
    thx for spotting the typo on the doAnAjax call. adding the callBack was the bit I was missing. in trawling through all the posts I had become confused, I misunderstood that the return needed to be declared, i thought it was automatic. Thx Art – art vanderlay Jul 20 '12 at 10:39
  • @artvanderlay: Note that `return callBack ( myRtnA )` should actually be `callBack ( myRtnA )`. The return value from the callback does not have any effect. – Felix Kling Jul 20 '12 at 11:15
4

As previously mentioned, using Callbacks.

function process(url, params, successCallback, errorCallback) {
    $.ajax({
        success : successCallback,
        error : errorCallback,
        data : params,
        url : url,
        type : 'POST',
        dataType : 'json'
    });
}

process(
    'http://www.google.co.uk', 
    { 
        param1 : 'a' 
    }, 
    function(resp) { 
        alert('Success');
    },
    function() {
        alert('Uh oh');
    }
);

You can then pass any function to process and it will be called on success/error.

Gavin
  • 6,284
  • 5
  • 30
  • 38
  • 2
    he specifically wanted synchronous behaviour though back to his original calling function. So he isn't actually looking for async behaviour, or atleast not from what he explains. – Jon Taylor Jul 20 '12 at 09:18
  • Based on the OP's code, he can consolidate it into the above code without having to use return values. Within the `successCallback` he can both `$('.rtnMsg').html(data);` and `resetForm($('#myForm'));` rather than having to return `success` or `error` and calling it there. – Gavin Jul 20 '12 at 09:22
  • I agree, and perhaps he hasn't understood the power of true asynchronous calls, hence why I haven't downvoted this answer. However if he truly does want synchronous behaviour then as per my answer switching the async flag from true to false would do the trick. – Jon Taylor Jul 20 '12 at 09:24
  • @Jon: What he wants is not necessarily what he needs. But anyway, specifically in his example, I don't see him call `doAnAjax` or use the (not existing) return value in any way. So there is no reason to make any assumptions how he uses `doAnAjax`. To me it actually looks like he tried to implement callbacks but did not get it to work. – Felix Kling Jul 20 '12 at 09:24
  • @Felix maybe he didnt use the return values because he doesn't know how, hence his question. Either way, I would still advise him to use asynchronous calls, however, he should know that there is the possibility of using synchronous calls too in case this is actually what he wanted. – Jon Taylor Jul 20 '12 at 09:26
  • @Gavin, thx for the answer, dont know who gave the down vote. – art vanderlay Jul 20 '12 at 10:41
  • @artvanderlay - Pah, SO is full of people with their own opinions. Unfortunately it's easy to downvote for that reason alone. Hope my answer helped? – Gavin Jul 20 '12 at 10:52
2

The answer is you don't, but it is easily achievable. The idea of AJAX is it is asynchronous, hence the A JAX. This means that the function that originally calls your ajax will not wait for it to complete and instead all work to be completed after an ajax call should be in the success or error handlers.

If you need something to be synchronous you can change your flag from async:true to async:false but then it becomes really a SJAX call (not even sure the term exists but, technically it isnt an AJAX call anymore).

Jon Taylor
  • 7,865
  • 5
  • 30
  • 55
  • For people from the future: 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 – ricks Mar 21 '19 at 20:27
0

Check out 'derferred' in jquery. The below example uses deferred.done with async turned off, and seems to work for me.!

$.ajax({
    url: "http://www.whatever.com/whatever",
    async: false }).done(function( data ) {
        alert(data); //or whatever
    })