0

I have some non-uniformity as to how my client-side jQuery handles my JSON ajax responses via server-side PHP.

Here are two example ajax calls I have:

function checkOrders() {

    $.ajax({
        type: "POST" ,
        url:"/service/index.php" ,
        data: {
            q: "checkOrders"
        } ,
        complete: function(result) {

            // note here the JSON.parse() clause
            var x = JSON.parse(result.responseText);

            if (x['unhandled_status']>0) {

                noty({
                    text: '<center>There are currently <b>'+x['unhandled_status']+'</b> unhandled Orders.',
                    type: "information",
                    layout: "topRight",
                    modal: false ,
                    timeout: 5000 
                    }
                });             

            }

        } ,

        xhrFields: {
            withCredentials: true
        }
    });

}

Note in the above example I have to JSON.parse() the responseText from my PHP page in order to deal with it as an object. It somehow sees the overall PHP response as an object, and I have to pull the responseText from that object and JSON.parse() it, in order to use it.

Now here is another ajax call that I have, whereby the returned response, I can use directly as a json response - meaning, somehow the PHP page does not return a full "object" but ONLY returns the json and my ajax call somehow already knows it is JSON and I do not need to JSON.parse() it:

function getUnfiledOrders() {

$.ajax({
    type: "POST" ,
    url:"/service/index.php" ,
    data: {
        queryType: "getUnfiledOrders"
    } ,
    success: function(result) {

        if (result['total_records'] >0) {
            noty({
                text: result['response'],
                type: "error",
                modal: false,
                dismissQueue: true,
                layout: "topRight",
                theme: 'defaultTheme'
            });
        }
    } ,
    xhrFields: {
        withCredentials: true
    }
});

}

In this case, I do not need to JSON.parse() the responseText in order to treat the response as a JSON object.

Both PHP response scripts look something like this:

 header('content-type:application/json');
 $array = array("total_records"=>3,"response"=>"SUCCESS");
 echo json_encode($array);

Can anybody clue me in on this non-uniformity?

EDIT:

I realized that I had two different callbacks in each of the above ajax calls. One was on complete and the other was on success.

When I switched them both to success the returned response from my ajax request was handled uniformly.

So I guess my question now is:

  • Why is there a non-uniformity between these two callbacks?
  • Which is better to use?
Walker Farrow
  • 3,579
  • 7
  • 29
  • 51

3 Answers3

3

I just thoroughly reviewed the docs on $.ajax() as covered here.

Anyway, the simplicity is that complete and success have different variables loaded in the function.

complete returns this:

complete
Type: Function( jqXHR jqXHR, String textStatus )

success returns this:

success
Type: Function( Anything data, String textStatus, jqXHR jqXHR )

When I have complete, the first parameter returned is an object so that is why I have to use:

complete: function(data) {
 var x = JSON.parse(data.responseText);
}

As I am having to fetch the responseText in the object that is returned - and it has a string value (not necessarily formatted as JSON).

The success function returns, as the first variable, whatever is passed through from PHP. In this case it is a json_encoded string. So it returns that and you can play around with it as soon as it is returned with no further manipulation.

Ta-dah!

In addition, note that .success() only gets called if server response is 200, .complete() will always get called regardless of status code

OneMoreQuestion
  • 1,693
  • 3
  • 25
  • 51
Walker Farrow
  • 3,579
  • 7
  • 29
  • 51
1

My previous response does not apply to your problem, although it is something you (and everyone) might need to be aware of.

Regarding your point about complete vs success -- yes, the returned values are in different order. Still, you don't need to parse the text on complete. The jqXHR response has a responseJSON object that you can use directly.

http://api.jquery.com/jQuery.ajax/#jqXHR

Previous Response

Are you calling checkOrders from a form, using a form button?

I have found that JQuery expects the data to be form-encoded in these case, regardless of you telling it you expect JSON.

jquery ajax returns success when directly executed, but returns error when attached to button, even though server response is 200 OK

Not sure if this is by design or a bug.

If this is your case, try changing form tag to div, or putting the button outside of the form.

Community
  • 1
  • 1
noderman
  • 1,934
  • 1
  • 20
  • 36
0

In your case I would just use $.getJSON like the following:

$.getJSON( "api.php", { user: "John", password: "1234" } )
  .done(function( json ) {
    console.log( "JSON object: " + json.friends[ 3 ].name );
  })
  .fail(function( jqxhr, textStatus, error ) {
    console.log( "Sorry, the request failed.");
});

This way you can make sure that the answer is always a js object.

Hope this helped, Sebastian

  • It would really help to explain why this was downvoted. It did solve your problem, right? Correct me if I'm wrong... – Sebastian Walker Nov 01 '15 at 15:58
  • how does an ajax call from a $.getJSON call? Maybe you can explain this a bit better. Does it always result in an object as oppose to an $.ajax() call? And again, I didn't downvote you.... – Walker Farrow Nov 01 '15 at 18:04
  • 1
    A getJSON call always results in an object, already parsed as JSON. It basically is a shorthand for .ajax() with some defaults set. More details here: http://api.jquery.com/jquery.getjson/ – Sebastian Walker Nov 01 '15 at 18:12
  • I see. Ok, and can you just clarify for me when I would want to use $.ajax() as opposed to $.getJSON()? After all, the point of ajax is that you are trying to get a response from the server. JSON is the standard these days so wondering if I am missing that there is some other use for the $.ajax() call... Tku! – Walker Farrow Nov 01 '15 at 18:54
  • 1
    Ajax is for requesting stuff from the server. You could request for example JSON to retrieve data from the server. But you could also use JSON to retrieve images or other things from the server. There's a lot of possibilities. getJSON just simplifies things for you by removing unnecessary clutter form your ajax function. That's what shorthands are for. :-) – Sebastian Walker Nov 01 '15 at 22:06