SearchBuilder 'null' bug?

SearchBuilder 'null' bug?

lisarushlisarush Posts: 102Questions: 17Answers: 0

Link to test case:

<body> 

<script>
$(function() {
   $('#nonexistentTable').DataTable();
});
</script>
</body>

Debugger code (debug.datatables.net):
Error messages shown:

in browser console:
Uncaught TypeError: ctx is undefined

Description of problem:

If dataTables is initialized for a table that does not exist, the SearchBuilder code dies at the following piece of code, when trying to access ctx. (It looks like there are other similar lines below.) If asking why we'd call on a non-existent table, the table is dynamically included/not on the page; usually jQuery-style calls handle missing items gracefully.

apiRegister('searchBuilder.getDetails()', function (deFormatDates) {
        if (deFormatDates === void 0) { deFormatDates = false; }
        var ctx = this.context[0];
        // If SearchBuilder has not been initialised on this instance then return
        return ctx._searchBuilder ?
            ctx._searchBuilder.getDetails(deFormatDates) :
            null;
    });

Replies

  • kthorngrenkthorngren Posts: 21,443Questions: 26Answers: 4,974
    edited February 2023

    Possibly you are using an older version of SearchBUlder but I don't see that problem with the current (1.4.0) in this test case:
    http://live.datatables.net/qumuqoda/1/edit

    Can you update the test case to show the issue or provide a link to your page?

    Kevin

  • lisarushlisarush Posts: 102Questions: 17Answers: 0

    Sorry, you are correct, that does work as in your example.
    (And we are on the latest version of the code.)

    Looking closer... our issue is actually with calling the getDetails() method itself. We add some extra styling to the table when SearchBuilder is turned on and has values pre-selected (via stateSave). We are currently using (table.searchBuilder !== undefined && table.searchBuilder.getDetails() !== null) to check that. In essence here, there really isn't a table -- however, a table object evidently does get built and returned by DataTables. I almost would have expected that the call to .DataTable() would have returned null & this would have been much more obvious as to the error here; instead, all goes along ok until accessing ctx inside getDetails().
    Do you have a suggestion on the best way to test for our case? Is there a good call to check that the table value that is returned is valid (that we could short-circuit things earlier on)? and/or a better way to check searchBuilder?

    Obviously, I could add other checks for specific tables to handle this. But, I would prefer a more generic/foolproof way to check.

  • kthorngrenkthorngren Posts: 21,443Questions: 26Answers: 4,974

    You can use the DataTable.isDataTable() to check if the table or non-existent table is a Datatable. For example:
    http://live.datatables.net/qumuqoda/2/edit

    Kevin

  • lisarushlisarush Posts: 102Questions: 17Answers: 0
    edited February 2023

    Hmm, at the point I'm running this, I no longer have access to the selector used to create the table. I was hoping for something that I could check on the table object that is returned. Ideally, something like:

    $(document).ready( function () {
      let table = $('#nonexistentTable').DataTable({ dom: 'Qfrtip' });
      // ...
      let tableExists = $.fn.DataTable.isDataTable(table);
      console.log( 'tableExists = ' + tableExists );
    } );
    

    but that returns true.

    Looks like I can check via table.context:
    let tableExists = table.context.length > 0;

    Or, better yet... I will check this & circumvent even calling DataTable in the first place:
    let selectorExists = this.length > 0;

    I should have played with this further before writing you. Thanks for your time and patience. :blush:

  • kthorngrenkthorngren Posts: 21,443Questions: 26Answers: 4,974
    edited February 2023

    Maybe you can set a variable with the jQuery selector, something like this:

    $(document).ready( function () {
      let htmlTable = $('#nonexistentTable')
      let table = $('#nonexistentTable').DataTable({ dom: 'Qfrtip' });
      // ...
      let tableExists = $.fn.DataTable.isDataTable( htmlTable );
      console.log( 'tableExists = ' + tableExists );
    } );
    

    You could change line 3 to use the variable like this:

    let table = htmlTable.DataTable({ dom: 'Qfrtip' });
    

    Kevin

  • lisarushlisarush Posts: 102Questions: 17Answers: 0
    edited February 2023

    Unfortunately, that is not an option -- as lines 2 and 3 from your example are actually contained in different methods in my case. But, I have it solved. Thanks.

    NOTE: I was initially just trying to mention the null case -- in case you wanted to add an extra check for that in a few of the methods.

  • kthorngrenkthorngren Posts: 21,443Questions: 26Answers: 4,974

    Looking at the DataTable.isDataTable() docs it does state that the Datatables API instance can be passed in. But that doesn't seem to work properly as you noted:
    http://live.datatables.net/yisupoto/1/edit

    @allan will need to take a look.

    Kevin

Sign In or Register to comment.