0

When I alert the returned value from the jsonServerResponse function, its value is undefined - despite JSON being returned from the process.php page.

function jsonServerResponse(operation, JSOoptionalData) {
        JSOoptionalData = (typeof JSOoptionalData == "undefined") ? 'defaultValue' : JSOoptionalData
        var jqxhr = $.ajax({
            type: "POST",
            url: "process.php",
            data: "apicommand=" + JSOoptionalData,
            success: function (json) {
                return jQuery.parseJSON(json);
            }
        });
}

alert("Response as JS Object: "+jsonServerResponse("operation"));

I know that the problem is that the alert function made before the asynchronous request is complete, but I am unsure how to fix this problem. Any advice is really appreciated :)

TaylorMac
  • 8,882
  • 21
  • 76
  • 104

3 Answers3

5

This is because the AJAX request is asynchronous, so the return is hit before the call completes, so the function always returns null.

You need to call the code which relies on the AJAX call, from within the success call back itself. Try this:

function jsonServerResponse(operation, JSOoptionalData) {
    JSOoptionalData = (typeof JSOoptionalData == "undefined") ? 'defaultValue' : JSOoptionalData
    var jqxhr = $.ajax({
        type: "POST",
        url: "process.php",
        data: "apicommand=" + JSOoptionalData,
        success: function (json) {
            alert("Response as JS Object: " + json);

            // to see more information about the object returned, use console.log:
            console.log(json);
        }
    });
}

jsonServerResponse("operation")
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • Is there any way to capture the data from the request into a variable outside of the success call back? – TaylorMac May 29 '12 at 08:39
  • 1
    @TaylorMac You can still put it into a global variable, but you have to be very careful to only use the variable once the AJAX call has completed. The best method is to call a function from your `success` handler, passing the result of the AJAX call. – Rory McCrossan May 29 '12 at 08:43
1

You nailed the problem, ajax is an async operation, you can use the returned data only in the success callback:

function jsonServerResponse(operation, JSOoptionalData) {
    // What that line suppose to do???
        JSOoptionalData = (typeof JSOoptionalData == "undefined") ? 'defaultValue' : JSOoptionalData
        var jqxhr = $.ajax({
            type: "POST",
            url: "process.php",
            data: "apicommand=" + JSOoptionalData,
            dataType: "json", // Change the dataType to json.
            success: function (json) {
                console.log("Response as JS Object:") 
                console.log(json);
            }
        });
}
gdoron
  • 147,333
  • 58
  • 291
  • 367
1

Ok, I figured it out from a different post. The result can either be handled within the success callback, or you can add an argument that is itself a callback function and apply the result of the ajax request to the callback.

function jsonServerResponse(operation, callback, JSOoptionalData) {
        JSOoptionalData = (typeof JSOoptionalData == "undefined") ? 'defaultValue' : JSOoptionalData
        jqxhr = $.ajax({
            type: "POST",
            contentType: "application/json",
            url: "process.php",
            data: "apicommand=" + operation + "&optionaldata" + JSON.stringify(JSOoptionalData),
            dataType: "json",
            success: function (json) {
                if(typeof callback === 'function') callback.apply(this, [json]);
            }
        });
}


jsonServerResponse("get_something_from_server", function(returnedJSO){
     console.log(returnedJSO.Result.Some_data);
}, "optional_data");

And gdoron, the line you have asked about makes the third argument optional. I hear it's good practice, if you are going to pass some data onto the server (but you dont know how many variables) to add an optional argument and just pass a js object, convert this to a JSON string, and decode it server-side.

Peace! :)

TaylorMac
  • 8,882
  • 21
  • 76
  • 104