405

I have an issue with Datatables. I also went through this link which didn't yield any results. I have included all the prerequisites where I'm parsing data directly into the DOM.

Script

$(document).ready(function() {
  $('.viewCentricPage .teamCentric').dataTable({
    "bJQueryUI": true,
    "sPaginationType": "full_numbers",
    "bPaginate": false,
    "bFilter": true,
    "bSort": true,
    "aaSorting": [
      [1, "asc"]
    ],
    "aoColumnDefs": [{
      "bSortable": false,
      "aTargets": [0]
    }, {
      "bSortable": true,
      "aTargets": [1]
    }, {
      "bSortable": false,
      "aTargets": [2]
    }],
  });
});
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Thriveni
  • 4,183
  • 2
  • 14
  • 12
  • 4
    can you show html of your table? – Ehsan Sajjad Aug 19 '14 at 07:28
  • sorry for not posting html..thank you for your concern..i fixed my problem :). – Thriveni Sep 16 '14 at 05:12
  • 17
    The "Cannot read property 'mData' of undefined" error also appears when using a well-formed thead with a colspan but without a second row to obtain one th per td – PaulH Nov 07 '14 at 21:42
  • run by commenting the .dataTable() function first, then see the table, you will find the issue in more cases – Rajdeep Dec 08 '17 at 06:53
  • thead or table heading column must be missing from the table,so script is not able to find that,please check your heading under thead or any column name – Rahul Jain Nov 13 '19 at 05:55

22 Answers22

850

FYI dataTables requires a well formed table. It must contain <thead> and <tbody> tags, otherwise it throws this error. Also check to make sure all your rows including header row have the same number of columns.

The following will throw error (no <thead> and <tbody> tags)

<table id="sample-table">
    <tr>
        <th>title-1</th>
        <th>title-2</th>
    </tr>
    <tr>
        <td>data-1</td>
        <td>data-2</td>
    </tr>
</table>

The following will also throw an error (unequal number of columns)

<table id="sample-table">
    <thead>
        <tr>
            <th>title-1</th>
            <th>title-2</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>data-1</td>
            <td>data-2</td>
            <td>data-3</td>
        </tr>
    </tbody>
</table>

For more info read more here

Dave Powers
  • 2,051
  • 2
  • 30
  • 34
Moses Machua
  • 11,245
  • 3
  • 36
  • 50
91

A common cause for Cannot read property 'fnSetData' of undefined is the mismatched number of columns, like in this erroneous code:

<thead>                 <!-- thead required -->
    <tr>                <!-- tr required -->
        <th>Rep</th>    <!-- td instead of th will also work -->
        <th>Titel</th>
                        <!-- th missing here -->
    </tr>
</thead>
<tbody>
    <tr>
        <td>Rep</td>
        <td>Titel</td>
        <td>Missing corresponding th</td>
    </tr>
</tbody>

While the following code with one <th> per <td> (number of columns must match) works:

<thead>
    <tr>
        <th>Rep</th>       <!-- 1st column -->
        <th>Titel</th>     <!-- 2nd column -->
        <th>Added th</th>  <!-- 3rd column; th added here -->
    </tr>
</thead>
<tbody>
    <tr>
        <td>Rep</td>             <!-- 1st column -->
        <td>Titel</td>           <!-- 2nd column -->
        <td>th now present</td>  <!-- 3rd column -->
    </tr>
</tbody>

The error also appears when using a well-formed thead with a colspan but without a second row.

For a table with 7 colums, the following does not work and we see "Cannot read property 'mData' of undefined" in the javascript console:

<thead>
    <tr>
        <th>Rep</th>
        <th>Titel</th>
        <th colspan="5">Download</th>
    </tr>
</thead>

While this works:

<thead>
    <tr>
        <th rowspan="2">Rep</th>
        <th rowspan="2">Titel</th>
        <th colspan="5">Download</th>
    </tr>
    <tr>
        <th>pdf</th>
        <th>nwc</th>
        <th>nwctxt</th>
        <th>mid</th>
        <th>xml</th>
    </tr>
</thead>
PaulH
  • 2,918
  • 2
  • 15
  • 31
  • 6
    Found your answer useful. My markup was missing the `tr` used to enclose all `th` elements. Just leaving it here in case somebody finds this useful! – Vikram Deshmukh Nov 26 '14 at 13:44
  • This answer also lead me to my solution. I was missing a `th` column in my `thead`, which was causing the error. The answer by Nathan Hanna also seems to indicate this issue too. – Paul Richter Nov 27 '14 at 03:53
  • this help me to see that i have a missing `th`in my `thead`too! – Demi Magus Jan 13 '15 at 22:41
  • Even four years on `colspan` interpretation is still a problem. I had to put in some blank `th` and no `colspan` to get rid of errors. But what a simple add on to get this functionality. BTW: Rails 5.1.5, Bootstrap 4.0.0. I just added the stylesheets and script CDNs, and `$(document).ready…` to the page. – Greg Mar 23 '18 at 00:57
  • @Greg Sorry, I don't understand. – PaulH Mar 23 '18 at 19:04
  • @PaulH The first two sentences or the rest? – Greg Mar 24 '18 at 04:22
64

Having <thead> and <tbody> with the same numbers of <th> and <td> solved my problem.

Masoud Darvishian
  • 3,754
  • 4
  • 33
  • 41
52

I had this same problem using DOM data in a Rails view created via the scaffold generator. By default the view omits <th> elements for the last three columns (which contain links to show, hide, and destroy records). I found that if I added in titles for those columns in a <th> element within the <thead> that it fixed the problem.

I can't say if this is the same problem you're having since I can't see your html. If it is not the same problem, you can use the chrome debugger to figure out which column it is erroring out on by clicking on the error in the console (which will take you to the code it is failing on), then adding a conditional breakpoint (at col==undefined). When it stops you can check the variable i to see which column it is currently on which can help you figure out what is different about that column from the others. Hope that helps!

debugging mData error

blurfus
  • 13,485
  • 8
  • 55
  • 61
Nathan Hanna
  • 4,643
  • 3
  • 28
  • 32
  • 1
    This was the only method that helped me solve my problem. Thank you! – Mike Crowe Mar 09 '15 at 18:37
  • Not sure you already mention this, but we can "watch" the variables on the right column and figure out which table is related. For my case it is the default rendering of Asp.Net table, which is not standardized when the table is empty. Thanks for the tip! – Hoàng Long Jul 08 '16 at 09:35
  • Thank you... Nathan for the debugging steps. It helped me. – Sachin Gaikwad Dec 14 '16 at 10:02
  • 1
    For me, the problem is fixed by adding thead and tbody element. – neolei Dec 26 '17 at 06:23
  • I have the same Rails setup, but I had named the last three columns "Details" with a `colspan="3"` but I got errors (that's how I ended up at this page). I fiddled around a bit, but finally gave up and created three `th` elements and with the first one "Details" and left the last two blank. The fiddling around suggested that dataTables has problems with colspan as the last in the series. The OP fix is odd in that the number of columns doesn't add up. I didn't have any conditions on the table, such as `order` or `sortable`. I did add those after I got it working. – Greg Mar 24 '18 at 04:38
  • **"I found that if I added in titles for those columns in a element within the that it fixed the problem."** – Zahari Kitanov May 30 '18 at 12:47
28

This can also occur if you have table arguments for things like 'aoColumns':[..] which don't match the correct number of columns. Problems like this can commonly occur when copy pasting code from other pages to quick start your datatables integration.

Example:

This won't work:

<table id="dtable">
    <thead>
        <tr>
            <th>col 1</th>
            <th>col 2</th>
        </tr>
    </thead>
    <tbody>
        <td>data 1</td>
        <td>data 2</td>
    </tbody>
</table>
<script>
        var dTable = $('#dtable');
        dTable.DataTable({
            'order': [[ 1, 'desc' ]],
            'aoColumns': [
                null,
                null,
                null,
                null,
                null,
                null,
                {
                    'bSortable': false
                }
            ]
        });
</script>

But this will work:

<table id="dtable">
    <thead>
        <tr>
            <th>col 1</th>
            <th>col 2</th>
        </tr>
    </thead>
    <tbody>
        <td>data 1</td>
        <td>data 2</td>
    </tbody>
</table>
<script>
        var dTable = $('#dtable');
        dTable.DataTable({
            'order': [[ 0, 'desc' ]],
            'aoColumns': [
                null,
                {
                    'bSortable': false
                }
            ]
        });
</script>
DrewT
  • 4,983
  • 2
  • 40
  • 53
13

One more reason why this happens is because of the columns parameter in the DataTable initialization.

The number of columns has to match with headers

"columns" : [ {
                "width" : "30%"
            }, {
                "width" : "15%"
            }, {
                "width" : "15%"
            }, {
                "width" : "30%"
            } ]

I had 7 columns

<th>Full Name</th>
<th>Phone Number</th>
<th>Vehicle</th>
<th>Home Location</th>
<th>Tags</th>
<th>Current Location</th>
<th>Serving Route</th>
David Dehghan
  • 22,159
  • 10
  • 107
  • 95
Siddharth
  • 9,349
  • 16
  • 86
  • 148
13

Tips 1:

Refer to this Link you get some Ideas:

https://datatables.net/forums/discussion/20273/uncaught-typeerror-cannot-read-property-mdata-of-undefined

Tips 2:

Check following is correct:

  • Please check the Jquery Vesion
  • Please check the versiion of yours CDN or your local datatable related .min & css files
  • your table have <thead></thead> & <tbody></tbody> tags
  • Your table Header Columns Length same like Body Columns Length
  • Your Using some cloumns in style='display:none' as same propery apply in you both Header & body.
  • your table columns no empty, use something like [ Null, --, NA, Nil ]
  • Your table is well one with out <td>, <tr> issue
venkatskpi
  • 800
  • 6
  • 8
9

You have to remove your colspan and the number of th and td needs to match.

NXT
  • 1,981
  • 1
  • 24
  • 30
Francisco Balam
  • 331
  • 3
  • 4
9

I faced the same error, when tried to add colspan to last th

<table>
  <thead>
    <tr>    
      <th>&nbsp;</th> <!-- column 1 -->
      <th colspan="2">&nbsp;</th> <!-- column 2&3 -->
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
  </tbody>
</table>

and solved it by adding hidden column to the end of tr

<thead>
  <tr>    
    <th>&nbsp;</th> <!-- column 1 -->
    <th colspan="2">&nbsp;</th> <!-- column 2&3 -->

    <!-- hidden column 4 for proper DataTable applying -->
    <th style="display: none"></th> 
  </tr>
</thead>

<tbody>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>

    <!-- hidden column 4 for proper DataTable applying -->
    <td style="display: none"></td>
  </tr>
</tbody>

Explanaition to that is that for some reason DataTable can't be applied to table with colspan in the last th, but can be applied, if colspan used in any middle th.

This solution is a bit hacky, but simpler and shorter than any other solution I found.

I hope that will help someone.

haz
  • 1,549
  • 15
  • 20
renkse
  • 502
  • 7
  • 15
7

I am getting a similar error. The problem is that the header line is not correct. When I did the following header line, the problem I was having was resolved.

<table id="example" class="table table-striped table-bordered" style="width:100%">
        <thead>
    <tr>
                <th colspan="6">Common Title</th>
            </tr>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Tiger Nixon</td>
                <td>System Architect</td>
                <td>Edinburgh</td>
                <td>61</td>
                <td>2011/04/25</td>
                <td>$320,800</td>
            </tr>
</tbody>
</table>
Fırat DİKMEN
  • 479
  • 5
  • 8
6

in my case this error occured if i use table without header

              <thead>
                   <tr>
                       <th>example</th>
                  </tr>
              </thead>
Krsna Kishore
  • 8,233
  • 4
  • 32
  • 48
Asad
  • 326
  • 2
  • 7
3

Slightly different problem for me from the answers given above. For me, the HTML markup was fine, but one of my columns in the javascript was missing and didn't match the html.

i.e.

<table id="companies-index-table" class="table table-responsive-sm table-striped">

                            <thead>
                            <tr>
                                <th>Id</th>
                                <th>Name</th>
                                <th>Created at</th>
                                <th>Updated at</th>
                                <th>Count</th>
                            </tr>
                            </thead>
                            <tbody>
                            @foreach($companies as $company)
                                <tr>
                                    <td>{{ $company->id }}</td>
                                    <td>{{ $company->name }}</td>
                                    <td>{{ $company->created_at }}</td>
                                    <td>{{ $company->updated_at }}</td>
                                    <td>{{ $company->count }}</td>
                                </tr>
                            @endforeach
                            </tbody>
                        </table>

My Script:-

<script>
        $(document).ready(function() {
            $('#companies-index-table').DataTable({
                serverSide: true,
                processing: true,
                responsive: true,
                    ajax: "{{ route('admincompanies.datatables') }}",
                columns: [
                    { name: 'id' },
                    { name: 'name' },
                    { name: 'created_at' },
                    { name: 'updated_at' },     <-- I was missing this line so my columns didn't match the thead section.
                    { name: 'count', orderable: false },
                ],
            });
        });
    </script>
Paul Wright
  • 384
  • 3
  • 9
3

I had a dynamically generated, but badly formed table with a typo. I copied a <td> tag inside another <td> by mistake. My column count matched. I had <thead> and <tbody> tags. Everything matched, except for this little mistake I didn't notice for a while, because my column had a lot of link and image tags in it.

Peter Szalay
  • 376
  • 3
  • 13
3

This one drove me crazy - how to render a DataTable successfully in a .NET MVC view. This worked:

 **@model List<Student>
 @{
    ViewData["Title"] = "Index";
}
 <h2>NEW VIEW Index</h2>
 <table id="example" class="display" style="width:100%">
   <thead>
   <tr>
   <th>ID</th>
    <th>Firstname</th>
    <th>Lastname</th> 
  </tr>
  </thead>
  <tbody>
@foreach (var element in Model)
{
    <tr>
    <td>@Html.DisplayFor(m => element.ID)</td>
    <td>@Html.DisplayFor(m => element.FirstName)</td>
    <td>@Html.DisplayFor(m => element.LastName)</td>
    </tr>

}
</tbody>
</table>**

Script in JS file:

**$(document).ready(function () {
    $('#example').DataTable();
});**
smac2020
  • 9,637
  • 4
  • 24
  • 38
3

For those working in Webforms using GridView:

Moses's answer is totally correct. But since we're generating the table, the thead tag isn't generated by default. So to solve the problem add [YourGridViewID].HeaderRow.TableSection = TableRowSection.TableHeader to your backend, below of the DataBind() method call (if you're using it). This configuration takes the HeaderText value of the Field in your GridView as the value of the th tag it generates inside the thead.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Bazil
  • 429
  • 4
  • 6
2

In my case, and using ASP.NET GridView, UpdatePanel and with DropDownList (with Chosen plugin where I reset value to zero using a Javascript line), I got this error and tried everything with no hope for days. The problem was that the code of my dropdown in code behind was as follows and when I select a value twice to apply its action to selected grid rows I get that error. I thought for days it's a Javascript issue (again, in my case) and finally the fix was giving zero for the drowpdown value with the update process:

  private void ddlTasks_SelectedIndexChanged(object sender, System.EventArgs e)
  {
     if (ddlTasks.SelectedValue != 0) {
        ChangeStatus(ddlTasks.SelectedValue);
        ddlTasks.SelectedValue = "0"; //// **This fixed my issue**
     }

     dvItemsGrid.DataSource = CreateDatasource();
     dvItemsGrid.DataBind();
     dvItemsGrid.UseAccessibleHeader = true;
     dvItemsGrid.HeaderRow.TableSection = TableRowSection.TableHeader;

  }

This was my fault:

     $('#<%= DropDownList.ClientID%>').val('0').trigger("chosen:updated").chosen();
hsobhy
  • 1,493
  • 2
  • 21
  • 35
  • The part here that worked for me was the `dvItemsGrid.HeaderRow.TableSection = TableRowSection.TableHeader;`. Otherwise the gridview doesn't render a ``. – Tony L. Sep 04 '20 at 17:09
2

I had encountered the same issue but I was generating table Dynamically. In my case, my table had missing <thead> and <tbody> tags.

here is my code snippet if it helped somebody

   //table string
   var strDiv = '<table id="tbl" class="striped center responsive-table">';

   //add headers
   var strTable = ' <thead><tr id="tableHeader"><th>Customer Name</th><th>Customer Designation</th><th>Customer Email</th><th>Customer Organization</th><th>Customer Department</th><th>Customer ContactNo</th><th>Customer Mobile</th><th>Cluster Name</th><th>Product Name</th><th> Installed Version</th><th>Requirements</th><th>Challenges</th><th>Future Expansion</th><th>Comments</th></tr> </thead> <tbody>';


  //add data
  $.each(data, function (key, GetCustomerFeedbackBE) {
                            strTable = strTable + '<tr><td>' + GetCustomerFeedbackBE.StrCustName + '</td><td>' + GetCustomerFeedbackBE.StrCustDesignation + '</td><td>' + GetCustomerFeedbackBE.StrCustEmail + '</td><td>' + GetCustomerFeedbackBE.StrCustOrganization + '</td><td>' + GetCustomerFeedbackBE.StrCustDepartment + '</td><td>' + GetCustomerFeedbackBE.StrCustContactNo + '</td><td>' + GetCustomerFeedbackBE.StrCustMobile + '</td><td>' + GetCustomerFeedbackBE.StrClusterName + '</td><td>' + GetCustomerFeedbackBE.StrProductName + '</td><td>' + GetCustomerFeedbackBE.StrInstalledVersion + '</td><td>' + GetCustomerFeedbackBE.StrRequirements + '</td><td>' + GetCustomerFeedbackBE.StrChallenges + '</td><td>' + GetCustomerFeedbackBE.StrFutureExpansion + '</td><td>' + GetCustomerFeedbackBE.StrComments + '</td></tr>';
                        });

//add end of tbody
 strTable = strTable + '</tbody></table>';

//insert table into a div                 
   $('#divCFB_D').html(strDiv);
   $('#tbl').html(strTable);


    //finally add export buttons 
   $('#tbl').DataTable({
                            dom: 'Bfrtip',
                            buttons: [
                                'copy', 'csv', 'excel', 'pdf', 'print'
                            ]
                        });
Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154
2

In addition to inconsistent and numbers, a missing item inside datatable scripts columns part can cause this too. Correcting that fixed my datatables search bar.

I'm talking about this part;

"columns": [
  null,
  .
  .
  .
  null
           ],

I struggled with this error till I was pointed that this part had one less "null" than my total thead count.

Ege Bayrak
  • 1,139
  • 3
  • 20
  • 49
1

in my case the cause of this error is i have 2 tables that have same id name with different table structure, because of my habit of copy-paste table code. please make sure you have different id for each table.

<table id="tabel_data">
    <thead>
        <tr>
            <th>heading 1</th>
            <th>heading 2</th>
            <th>heading 3</th>
            <th>heading 4</th>
            <th>heading 5</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>data-1</td>
            <td>data-2</td>
            <td>data-3</td>
            <td>data-4</td>
            <td>data-5</td>
        </tr>
    </tbody>
</table>

<table id="tabel_data">
    <thead>
        <tr>
            <th>heading 1</th>
            <th>heading 2</th>
            <th>heading 3</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>data-1</td>
            <td>data-2</td>
            <td>data-3</td>
        </tr>
    </tbody>
</table>
Baim Wrong
  • 478
  • 1
  • 10
  • 14
0

You need to wrap your your rows in <thead> for the column headers and <tbody> for the rows. Also ensure that you have matching no. of column headers <th> as you do for the td

William
  • 740
  • 2
  • 11
  • 18
0

I may be arising by aoColumns field. As stated HERE

aoColumns: If specified, then the length of this array must be equal to the number of columns in the original HTML table. Use 'null' where you wish to use only the default values and automatically detected options.

Then you have to add fields as in table Columns

...
aoColumnDefs: [
    null,
    null,
    null,
    { "bSortable": false },
    null,
],
...
-3

I found some "solution".

This code doesn't work:

<table>
<thead>
    <tr>
        <th colspan="3">Test</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
    </tr>
</tbody>

But this is ok:

<table>
<thead>
    <tr>
        <th colspan="2">Test</th>
        <th></th>
    </tr>
</thead>
<tbody>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
    </tr>
</tbody>

I think, that the problem is, that the last TH can't have attribute colspan.

kluvi
  • 67
  • 4