Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot .catch() an error when using Jquery.ajax().then()

I am hitting a number of API's from JQuery, and caching the result of each so that the data can be re-used multiple times in the page to render some dashboard widgets in different formats.

The problem is that if an API returns a 500 status code with error, I don't want to try and draw the widget, but capture the error in a friendly way.

However, I cannot figure out how .catch works with the JQuery.ajax() function. After reading here, here, here, here and a dozen others, I've got so far but always get the same console error:

TypeError: LoadDataFromApi(...).then(...).catch is not a function

I've tried to comment the code to explain what I'm trying to do at each stage. Please somebody explain why the whole .catch thing isn't working for me.

// Cache object to save API data for re-use
var requestCache = {};

// Get API data and save to cache 
function LoadDataFromApi(apiUrl) {
    if (!requestCache[apiUrl]) {
        var result = $.ajax({
            type: 'GET',
            url: apiUrl,
            dataType: "json",
            statusCode: {
                500: function (xhr) {
                    var err = JSON.parse(xhr.responseText);
                    console.log('Message:' + err.Message);
                    // throw err.Message; // removed because this was always an "uncaught exception", even if used within try/catch
                },
                200: function (xhr) {
                    // Do nothing here - put result into cache regardless of status code
                }
            }
        });
        requestCache[apiUrl] = result; // save the JSON data into cache
    }
    return requestCache[apiUrl];
}

// Called by page on load
function LoadJsonData() {
    LoadDataFromApi('/api/GetFoo?Row=10')
        .then(function (data) {
            RenderChart(data, 'Removed for legibility');
        })
        .catch(function (error) {
            console.log('Promise catch: ' + error);
        });
    LoadDataFromApi('/api/GetFoo?Row=10') // this returns cached data because API has already been hit
        .then(function (data) {
            RenderChart(data, 'Removed for legibility');
        })
        .catch(function (error) {
            console.log('Promise catch: ' + error);
        });
    LoadDataFromApi('/api/GetBar')
        .then(function (data) {
            RenderChart(data, 'Removed for legibility');
        })
        .catch(function (error) {
            console.log('Promise catch: ' + error);
        });
}
like image 894
EvilDr Avatar asked Oct 12 '18 10:10

EvilDr


People also ask

What is the best way to handle errors thrown in jQuery?

If you are using the latest version of jQuery (3.1), then you can take advantage of the newly introduced handler called jQuery.readyException () which handles the errors thrown synchronously in functions wrapped in $.jQuery.

How does the Ajax error function work?

The Ajax error function has three parameters: In truth, the jqXHR object will give you all of the information that you need to know about the error that just occurred. This object will contain two important properties:

What are the different types of exceptions caught by jQuery?

There are two types of Exceptions which is caught by jQuery. 1. When exception object is in the form of JSON object. 2. When exception object is in the form of plain text or HTML.

What happens when an Ajax request fails?

statusText: If the Ajax request fails, then this property will contain a textual representation of the error that just occurred. If the server encounters an error, then this will contain the text “Internal Server Error”.


2 Answers

Use .fail() as described in your first link here

Depending on your jQ version

"Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are removed as of jQuery 3.0. You can use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead."

EDIT: You error callback should accept 3 arguments, so make it so

function(jqXHR,textStatus,errorThrown ){}
like image 57
MKougiouris Avatar answered Sep 20 '22 15:09

MKougiouris


JQuery does not return typical promise, it's$.Deferred in that case:

  • http://api.jquery.com/jquery.ajax/
  • http://api.jquery.com/category/deferred-object/

More on that here, with answers: Deferred versus promise

like image 26
SzybkiSasza Avatar answered Sep 17 '22 15:09

SzybkiSasza