0

I am new to AJAX and I need to find a way to return an AJAX JSON response back to the calling function. Is there any way to achieve this. My code snippet:

function requestAjaxWebService(webServiceName, method, jsonData) {
    var returnData;
    $.ajax({
        url: webServiceName,
        type: method,
        data : jsonData,
        dataType: "json",
        success: function (data) {
            returnData = data;
        },
        error: function(error){
            returnData = "Server error";
        }
    });
    return returnData;
}
emceearjun
  • 13
  • 3
  • You could make the request synchronous which will wait for the request to complete before continuing execution, but this can cause problems elsewhere. – wpercy Jan 25 '16 at 16:29

2 Answers2

1

jQuery.ajax() performs asynchronous HTTP request. Hence, you can't return its response synchronously (which your code is trying to do).

If the request succeeds, the success(data, textStatus, jqXHR) handler will get called at some point (you don't know when).

Here is one way you could modify your code:

function requestAjaxWebService(webServiceName, method, jsonData, callback) {
    $.ajax({
        url: webServiceName,
        type: method,
        data : jsonData,
        dataType: "json",
        success: function (data, textStatus, jqXHR) {
            callback(true, data); // some method that knows what to do with the data
        },
        error: function(jqXHR, textStatus, errorThrown){
            callback(false, errorThrown);
        }
    });
}

callback should be a reference to a method like:

function onData(isSuccess, dataOrError)
{
    if (isSuccess) {
        // do something with data
    } else {
        console.error(dataOrError);
    }
}

Update If the settings object is needed in the callback for some reason:

function onData(isSuccess, settings, jqXHR, errorThrown)
{
    if (isSuccess) {
        // do something with the data:
        // jqXHR.responseText or jqXHR.responseXML
    } else {
        // do something with error data:
        // errorThrown, jqXHR.status, jqXHR.statusText, jqXHR.statusCode()
    }
}

function requestAjaxWebService(webServiceName, method, jsonData, callback) {
    var settings = {
        url: webServiceName,
        type: method,
        data : jsonData,
        dataType: "json"
    };
    settings.success = function(data, textStatus, jqXHR){
        callback(true, settings, jqXHR);
    };
    settings.error = function(jqXHR, textStatus, errorThrown){
        callback(false, settings, jqXHR, errorThrown);
    };
    $.ajax(settings);
}

requestAjaxWebService("name", "POST", "json", onData);

You can also use .done() and .fail() callbacks of jqxhr object instead of callbacks in settings object, as obiTheOne's answer suggests. It may look neater, but is not actually important here.

Michael Antipin
  • 3,522
  • 17
  • 32
  • thanks for the response. But I need to get the whole object back to the calling function of requestAjaxWebService and not a separate callback. Is there any way to achieve that? – emceearjun Jan 25 '16 at 17:04
  • What do you mean by the 'whole object'? Is it the one you pass to `$.ajax()`? See update to the answer. – Michael Antipin Jan 26 '16 at 08:38
  • jqXHR object actually contains all off the response data... The only reason I can imagine for needing settings object returned to success callback is having sent json data handy. – Michael Antipin Jan 26 '16 at 09:19
1

jQuery.ajax is an asynchronous function, so normally it doesn't return anything.

You can anyway return a value to the original function by setting the async option to false, but is not recommended, because a synchronous request will block the rest execution of the rest of your code until a response will be returned.

function requestAjaxWebService(webServiceName, method, onSuccess, onFail) {
    var returnData;
        $.ajax({
            url: webServiceName,
            type: method,
            async: false,
            data : jsonData,
            dataType: "json",
            success: function (data) {
                returnData = data;
            },
            error: function(error){
                returnData = "Server error";
            }
        });
    }

take a look at this example: jsbin sync ajax example

You should instead use a callback (the standard way) to handle the response

function onSuccess (data) {
  console.log(data);
}

function onFail (error) {
  console.log('something went wrong');
}

function requestAjaxWebService(webServiceName, method, onSuccess, onFail) {
    $.ajax({
        url: webServiceName,
        type: method,
        data : jsonData,
        dataType: "json",
        success: onSuccess,
        error: onError
    });
}

Or you can return a Promise (a sort of async object) that will change value as soon as the request will be fullfilled

function requestPromise (webServiceName, method) {
    return $.ajax({
        url: webServiceName,
        type: method,
        data : jsonData,
        dataType: "json"
    });
}

requestPromise('...', 'GET').done(function (data) {
    console.log(data);
});

refs: jquery.ajax params

obiTheOne
  • 105
  • 2
  • 5
  • `$.ajax()` returns jqxhr object, that provides `.done()`, `.fail()` and `.always()` handlers. Otherwise you are right, this may be a cleaner way as compared to using callbacks. – Michael Antipin Jan 26 '16 at 08:46