0

I have a data table that displays transaction counts by the hour, from 00 to 23. As such depending on when the report is being viewed number of columns changes. Columns are therefore created dynamically. It works for showing today's data (I see 10 columns from 00 to 09). When I try to view yesterday's data (00 - 23), it shows javascript error in data table's js file.

Below is the code and error message:

<div id="divGrid" style="clear: both">
    <table id="txnTable" class="table table-striped table-bordered table-hover display responsive compact" style="width: 100%;">
    </table>
</div>

Parameter SelDate is initially today's date and user can change using a calendar control.

function populateTable() {
    $.ajax({
        type: "POST",
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        cache: false,
        url: '../WebService/ABC.asmx/GetTransactionCountByDay',
        data: JSON.stringify({ SelDate: selDate, LogType: -1 }),
    }).done(function (result) {debugger
        jResult = JSON.parse(result.d);
        var columnNames = [];
        var tblData = [];

        //result.forEach(item => {  // IE can't handle this
        jResult.forEach(function(item) {
            // build an object containing the column names:
            columnNames.push({ title: item.HR });
            // build an array containing the one row data
            tblData.push(item.TXN_COUNT);
        });

        if ($.fn.DataTable.isDataTable(tblTxn)) {
            tblTxn.destroy();
        }

        tblTxn = $('#txnTable').DataTable({
            destroy: true,
            data: [tblData],
            columns: columnNames
        });
    }).fail(function (jqXHR, textStatus, errorThrown) {debugger
        alert(jqXHR.responseText);
    });
}

When selected date is changed and "Submit" button clicked:

$(document).on("click", "#lblSubmit", function (event) {
    populateTable();
});

Sample data received from ajax call:

[
  {
    "DT": "2021-10-20",
    "HR": "00",
    "TXN_COUNT": 138
  },
  {
    "DT": "2021-10-20",
    "HR": "01",
    "TXN_COUNT": 235
  },
  {
    "DT": "2021-10-20",
    "HR": "02",
    "TXN_COUNT": 111
  },
  {
    "DT": "2021-10-20",
    "HR": "03",
    "TXN_COUNT": 120
  },
  {
    "DT": "2021-10-20",
    "HR": "04",
    "TXN_COUNT": 120
  },
  {
    "DT": "2021-10-20",
    "HR": "05",
    "TXN_COUNT": 120
  },
  {
    "DT": "2021-10-19",
    "HR": "06",
    "TXN_COUNT": 318
  },
  {
    "DT": "2021-10-20",
    "HR": "07",
    "TXN_COUNT": 505
  },
  {
    "DT": "2021-10-20",
    "HR": "08",
    "TXN_COUNT": 294
  },
  {
    "DT": "2021-10-20",
    "HR": "09",
    "TXN_COUNT": 95
  }
]

Error:

"Uncaught TypeError: Cannot read properties of undefined (reading 'style')"

A screen shot of error message from Chrome debugger is also attached. enter image description here

6
  • Usually this error occurs when the number of columns defined in your HTML does not equal the number of columns defined/initialized in your JS. Commented Oct 20, 2021 at 15:15
  • @BeerusDev thanks. But in HTML I haven't defined any columns. Columns are added dynamically in populateTable() function. I also destroy the table before recreating it. I checked and columnNames array and tblData array have same number of rows. Commented Oct 20, 2021 at 17:45
  • Where it dies in datatable javascript is "... n[v].style.width=null!==r.sWidthOrig&& ..." and I can see length of n is 14 and v is also 14 which makes n[v] out of bounds. Coincidentlally, 14 is number of elements in columnNames array (hours 00 .. 13). Commented Oct 20, 2021 at 18:02
  • Seems like somehow that "count" lingers on; doing today's date, which works fine, I get 14 columns, from 00 to 13. Then I try to check yesterday's data, which has 24 columns and it dies. Could be that variable "n" is still having a length of 14. Not sure, losing hair by the hour! Commented Oct 20, 2021 at 18:13
  • 1
    OK, figured it out. Posting solution. Commented Oct 20, 2021 at 19:44

1 Answer 1

2

One newbie error (!) and one modification:

Modification:

Removed table from DOM and in populateTable() emptied its parent div and recreated it. For completeness, destroyed jquery datatable, if existed.

Newbie error:

my tblTxn.destroy() was missing the parameter; should have been tblTxn.destroy(true);

Final code:

function populateTable() {
    $.ajax({
        type: "POST",
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        cache: false,
        url: '<%= ResolveUrl("../WebService/ABC.asmx/GetTransactionCountByDay") %>',
        data: JSON.stringify({ SelDate: selDate, LogType: -1 }),
    }).done(function (result) {
        jResult = JSON.parse(result.d);
        var columnNames = [];
        var tblData = [];

        if ($.fn.DataTable.isDataTable(tblTxn)) {
            tblTxn.destroy(true);
        }
        $("divGrid").empty();  // Empty parent div, where jquery datatable resided
        $('<table>', { class: 'table table-striped table-bordered table-hover display responsive compact divGrid', id: 'txnTable', style: 'width: 100%;' }).appendTo("#divGrid");

        // result.forEach(item => {
        jResult.forEach(function(item) {  // IE version, since it doesn't understand '=>'
            // build an object containing the column names:
            columnNames.push({ title: item.HR });
            // build an array containing the one row data
            tblData.push(item.TXN_COUNT);
        });
        tblTxn = $('#txnTable').DataTable({
            destroy: true,
            data: [tblData],
            columns: columnNames
        });
    }).fail(function (jqXHR, textStatus, errorThrown) {
        alert(jqXHR.responseText);
    });
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.