Capturing errors on ajax.reload( ) calls

Capturing errors on ajax.reload( ) calls

OzPenguinOzPenguin Posts: 14Questions: 3Answers: 0
edited November 2016 in Free community support

I have the following code, which is called from the search form's search button

It works great when the ajax call returns rows, but if no rows were found or the search hit an error (eg json encode found invalid UTF-8 characters) then the search button is left disabled and the wait/progress mouse cursor is left active on the page.

It there a way to capture the error / empty result set on the ajax.reload( ) function ?

Am I going about this the wrong way ? Maybe I should be loading the ajax call directly into an array and then populating the DataTable from the array and not have it make the ajax calls directly

function Search()
{
    console.log("in Search()");
    $("body").css("cursor", "progress");
    $("#SearchButton").attr('disabled',true);
    
    table = $("#ProductList").DataTable();
    table.clear();
    table.draw();
    ClearForm('EditForm');
    
    table.ajax.reload( function (json) {
        $('#ProductList tbody tr:eq(0)').click();
        $("body").css("cursor", "default");
        $("#SearchButton").attr('disabled',false);
    } );
    
    console.log("Search() - returning false");
    
    return false;
}

thanks

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,552Questions: 1Answers: 10,477 Site admin

    If there is a JSON parsing error, the only way to catch the error is with the $.fn.dataTable.ext.errMode option as a function.

    Aside from that, perhaps a better option, if you are expecting invalid UTF8 characters, would be to make your own Ajax call ($.ajax) and use clear() and rows.add() to clear the table and then add the newly retrieved rows.

    Allan

  • OzPenguinOzPenguin Posts: 14Questions: 3Answers: 0

    Allan

    the UTF8 errors occur for me because the data source in not fully in my control and the data has been affected by MS products like word and excel. I know there are functions that can clean the data up, but that is not the point I am pursuing at the moment.

    In these events, the PHP script that is servicing the ajax calls fails to encode the JSON and returns a plain text error message (not ideal), but I am not sure how it should be done more elegantly yet.

    When the PHP finds no matching rows, then {} is returned. Maybe this is wrong too

    It sounds like this PHP script is the real cause of my issues.

    Please excuse this poor hacker

    cheers
    OzPenguin

  • allanallan Posts: 63,552Questions: 1Answers: 10,477 Site admin

    When the PHP finds no matching rows, then {} is returned. Maybe this is wrong too

    If DataTables is expecting the data to be in a data property it should return { "data": [] } when there are no rows found. If it is not looking inside a property, but rather getting an array at the top level, the server should be returning [] for no rows.

    Allan

  • OzPenguinOzPenguin Posts: 14Questions: 3Answers: 0

    Allan

    returning { "data": [] } instead of {} made no difference to how the program handled empty result sets.

    I am including the DataTable create code for reference:

        $('#ProductList').DataTable( {
            ajax: { 
                url: 'data',
                method: 'post',
                data: function ( d ) {
                    return $.extend( {}, d, {
                        "SearchPLU": $('#SearchPLU').val(),
                        "SearchLongDescription": $('#SearchLongDescription').val(),
                        "SearchSize": $('#SearchSize').val(),
                        "SearchSupplier": $('#SearchSupplier').val(),
                        "SearchOrderNumber": $('#SearchOrderNumber').val(),
                        "SearchAPN": $('#SearchAPN').val(),
                        "SearchDepartment": $('#SearchDepartment').val(),
                        "SearchProductGroup": $('#SearchProductGroup').val(),
                        "SearchSalesGroup": $('#SearchSalesGroup').val(),
                        "SearchHostFile": $('#SearchHostFile').val(),
                        "SearchHostSupplier": $('#SearchHostSupplier').val(),
                        "SearchHostSubRange": $('#SearchHostSubRange').val(),
                        "SearchDeleted": $('#SearchDeleted').prop("checked"),
                        "SearchStocked": $('#SearchStocked').prop("checked")
                    } );
                },
                dataSrc: ''
            },
            searching: false,
            paging: false,
            //info: false,
            sort: true,
            scrollY: 215,
            rowId: 'Id',
            select: 'single',
            columns: [
                { "data": "PLU" },
                { "data": "LongDescription" },
                { "data": "Size" },
                { "data": "Supplier" },
                { "data": "OrderNumber" }
            ],
            "fnInitComplete": function(oSettings, json) { $('#ProductList tbody tr:eq(0)').click(); }
        } );
    
  • OzPenguinOzPenguin Posts: 14Questions: 3Answers: 0

    FYI, I have added the following dataType: "json" to the front end code (at line 23 of previous post) and following line to the back end PHP code.

    header('Content-type: application/json');
    

    This still does not seem to handle the empty result set correctly.

  • allanallan Posts: 63,552Questions: 1Answers: 10,477 Site admin

    dataSrc: ''

    since you have that parameter (which I didn't know before), returning [] when there are no rows to show is what should be done (i.e. empty array).

    Allan

  • OzPenguinOzPenguin Posts: 14Questions: 3Answers: 0

    Allan

    tried returning [] and also { [] } and neither made any difference.

    Then I changed dataSrc: '' to dataSrc: 'data' and changed the back end to return the following on an empty result set

    {
        "result": "success",
        "data": []
    }
    

    which also did not effect the bahaviour.

  • allanallan Posts: 63,552Questions: 1Answers: 10,477 Site admin

    If you could link to the page in question and give me details on how to reproduce the error I'd be happy to take a look at it and help debug the issue.

    Allan

  • OzPenguinOzPenguin Posts: 14Questions: 3Answers: 0
    edited December 2016

    Allan

    sorry, it took a couple of days, but I have managed to make a copy of the page in question onto another site and remove the security and identifying marks

    https://discussion39152.withmylittleeye.com

    the database contains real product but the cost and sell prices have all been set to $4 and $5 respectively.

    Searching on product Description using XXXX will find you 42 valid products, searching for ZZZZ will find nothing and cause the problem I am referring to. Note that I have removed the disabling of the Search button, so you wont need to reload the page when no rows are returned, but the hourglass/wait mouse point will still be left on.

    thanks

  • allanallan Posts: 63,552Questions: 1Answers: 10,477 Site admin
    Answer ✓

    When there are no results there is a Javascript error occurring:

    :724 Uncaught TypeError: Cannot read property 'StandardCost' of undefined

    in this line:

    var StandardCostWithTaxes = data.StandardCost * (1 + data.GSTTaxRate / 100) * (1 + data.WETRate / 100);

    It looks like your code is assuming that there will be data. It needs to check that there actually is before then using it. Perhaps a simple if ( ! data ) { return; } would be all that is needed.

    Allan

  • OzPenguinOzPenguin Posts: 14Questions: 3Answers: 0

    Allan

    thankyou, that has resolved my issue

    Yes, I did assume that when I coded:

    $('#ProductList tbody').on( 'click', 'tr', function () {
        ...
    } );
    

    that it would only be called if I actually had a row, but now I understand that when adding the following code:

        table.ajax.reload( function (json) {
            $('#ProductList tbody tr:eq(0)').click();
            $("body").css("cursor", "default");
        } );
    

    that the click will occur even when no rows exist.

    The other thing that you have taught me is that when code reaches an unexpected error (like what you pointed out above), it is not just the current function that is aborted, it is the entire thread of execution that is aborted, so the default cursor code (above) is never returned to.

    Thanks again for taking the time to investigate my issue so thoroughly

    regards
    OzPenguin

  • allanallan Posts: 63,552Questions: 1Answers: 10,477 Site admin

    A pleasure. Great to hear that it is working now!

    Allan

This discussion has been closed.