views:

928

answers:

3

I am using jQuery to make an AJAX request to a remote endpoint. That endpoint will return a JSON object if there is a failure and that object will describe the failure. If the request is successful it will return HTML or XML.

I see how to define the expected request type in jQuery as part of the $.ajax() call. Is there a way to detect the request type in the success handler?

$.ajax(
    {
        type: "DELETE",
        url: "/SomeEndpoint",
        //dataType: "html",
        data:
            {
                "Param2": param0val,
                "Param1": param1val
            },
        success: function(data) {
                //data could be JSON or XML/HTML
            },
        error: function(res, textStatus, errorThrown) {
                alert('failed... :(');
            }
    }
);
A: 

By the time it calls your success handler, the data has already been deserialized for you. You need to always return the same data type for any successful result. If there truly is an error, you should probably throw an exception and let it get handled by the error callback instead. This should be able to parse the resulting error and package it for your callback, that is, it will detect that the response did not have 200 OK status and parse the result to obtain the error information.

tvanfosson
I have a method that returns JSON in some cases and HTML in others. The reason it returns a JSON description of the errors is because it's an object that describes all the server side data validation errors. It seems like the appropriate pattern to use. Disagree?
spoon16
+4  A: 

Have you application generate correct Content-Type headers (application/json, text/xml, etc) and handle those in your success callback. Maybe something like this will work?

xhr = $.ajax(
    {
        //SNIP
        success: function(data) {
                var ct = xhr.getResponseHeader('Content-Type');
                if (ct == 'application/json') {
                    //deserialize as JSON and continue
                } else if (ct == 'text/xml') {
                    //deserialize as XML and continue
                }
            },
         //SNIP
);

Untested, but it's worth a shot.

dowski
although Owen's response is appropriate the complete callback doesn't get the data so you have to use a similiar pattern of (store data outside of method scope... process in complete). I went with this method because I thought it was cleaner.
spoon16
+3  A: 

how about using the complete option?

$.ajax({
   ...

   complete : function(xhr, status) {
   // status is either "success" or "error"
   // complete is fired after success or error functions
   // xhr is the xhr object itself

       var header = xhr.getResponseHeader('Content-Type');
   },

   ...
});
Owen
Yeah, this is even better than what I suggested.
dowski