Alerting data from a cell when it is clicked upon throws 'TypeError: data is undefined'

Alerting data from a cell when it is clicked upon throws 'TypeError: data is undefined'

brassbonanzabrassbonanza Posts: 6Questions: 1Answers: 0
edited July 2018 in Free community support

I'm using flask as the webframework and passing the data in as follows:

return jsonify({'data': roles_list})

here is the call I am using to get the data on cell click:

    <script>
        $(document).ready(function () {
            var table = $('#roles_table').DataTable();
            console.log(table)
            $('#roles_table tbody').on('click', 'td', function () {
                var data = (table.cell(this).data())
                console.log(data)
            });
        });
    </script>

and the html where the data lives (the data is dynamically produced from a database):

                        <div class="col-md-4">
                            <table id="roles_table" class="table table-hover">
                                <thead>
                                    <tr>
                                        <th>Available Roles</th>
                                    </tr>
                                </thead>
                            </table>
                        </div>

I get returned in the console log (undefined) everytime for the cell data. If I log the table variable then I get the table object I am seeking.

Any help would be greatly appreciated.

This question has an accepted answers - jump to answer

Answers

  • brassbonanzabrassbonanza Posts: 6Questions: 1Answers: 0

    Update:

    This is what the table looks like when inspected in browser:

    <tbody>
     <tr role="row" class="odd">
    <td class="sorting_1">spectator</td></tr>
    <tr role="row" class="even"><td class="sorting_1">network-admin</td</tr>
    <tr role="row" class="odd"><td class="sorting_1">dynamodb-test</td></tr>
    <tr role="row" class="even"><td class="sorting_1">developer</td></tr>
    </tbody>
    
  • kthorngrenkthorngren Posts: 21,211Questions: 26Answers: 4,928

    Your JS code works here:
    http://live.datatables.net/natofavu/1/edit

    How are you adding the data to the table?

    It doesn't look like Datatables is adding the data. So if Datatables is initialized first then the data is added later directly into the HTML then Datatables won't know about it and it's data cache will be empty. Either you can use rows.add() to have Datatables populate the data or use something like rows().invalidate() to have Datatables refresh its cache after you've populated the HTML table directly.

    Kevin

  • brassbonanzabrassbonanza Posts: 6Questions: 1Answers: 0

    @kthorngren I am populating the table with an ajax call using datatables

                             $('#roles_table').DataTable({"ajax": "/_get_roles"});
    
  • kthorngrenkthorngren Posts: 21,211Questions: 26Answers: 4,928

    Ok, you didn't show that above. I updated the test case to use ajax like you have and it still works:
    http://live.datatables.net/monamire/1/edit

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

    Kevin

  • brassbonanzabrassbonanza Posts: 6Questions: 1Answers: 0

    Apologies for not mentioning that above.

    I am only running my application on localhost currently. It's interesting that yours work because I don't see any differences that we have except that you have defined <td> and <tbody> in your html where mine is created through the ajax call (I am assuming as it appears when I inspect the element with the page live).

    ...

    My data is inserted as a json object from flask is the way to access cell data different on click from json inserted data than html sourced data?

    I'm trying to think of a creative way to show you what I am seeing. ideas? I'm quite lost on this issue.

    Thank you for your help

  • kthorngrenkthorngren Posts: 21,211Questions: 26Answers: 4,928

    is the way to access cell data different on click from json inserted data than html sourced data?

    Did you look at my second example? It uses ajax not html based data with the same code to get the data.

    Maybe you can out this to make sure you are getting what is expected:

            $('#roles_table tbody').on('click', 'td', function () {
                var data = (table.cell(this).data())
                console.log(this)
            });
    

    Can you post more of your JS code so we can see the order of operations, etc.

    Kevin

  • brassbonanzabrassbonanza Posts: 6Questions: 1Answers: 0
    edited July 2018

    This is what is outputted by logging 'this'

    (apologies for some data name changes roles_table is now groups because of what I wanted to describe)

    Here is some more JS

        <script>
            $(document).ready(function () {
                $('#user_selection_form').on('submit', function (e) {
                    $.ajax({
                        type: 'post',
                        url: '/user_request',
                        data: $('#user_selection_form').serialize(),
                        success: function (q) {
                            $('#groups_table').dataTable().fnDestroy();
                            $('#groups_table').DataTable({"ajax": "/_get_groups"});
                        }
                    });
                    e.preventDefault();
                });
            });
        </script>
        <script>
            $(document).ready(function () {
                var table = $('#groups_table').DataTable();
                $('#groups_table tbody').on('click', 'td', function () {
                    var data = (table.cell(this).data());
                    console.log(this);
                });
            });
        </script>
    
  • kthorngrenkthorngren Posts: 21,211Questions: 26Answers: 4,928
    Answer ✓

    The above code helped. I was able to recreate your issue here:
    http://live.datatables.net/hibehaya/1/edit

    I think the problem is when you destroy and recreate the Datatable the function setup for the click event becomes stale as destroy() removes event listeners etc.

    I restructured my test case a bit to make it work:
    http://live.datatables.net/fuxohahi/1/edit

    Basically it re-adds the event listener each time Datatables initializes via the init event. Alternatively you could use initComplete to invoke the click event listener.

    As a bonus I added the use of $.fn.dataTable.isDataTable() to make sure a Datatables has been initialized before destroying.

    BTW, the $('#groups_table').dataTable().fnDestroy(); code is legacy Datatables. Although it works its recommended to use the current API, destroy().

    HTH,
    Kevin

  • brassbonanzabrassbonanza Posts: 6Questions: 1Answers: 0

    Kevin,

    Thank you for your help! I was able to tweak it a little bit to work with my current configuration I may tweak further in the future to work with how you showed.

    This is what I ended up doing:

        <script>
            $(document).ready(function () {
                $('#user_selection_form').on('submit', function (e) {
                    $.ajax({
                        type: 'post',
                        url: '/user_request',
                        data: $('#user_selection_form').serialize(),
                        success: function (q) {
                            if ($.fn.DataTable.isDataTable('#groups_table')) {
                                $('#groups_table').DataTable().destroy();
                            }
                            if ($.fn.DataTable.isDataTable('#policies_table')) {
                                $('#policies_table').DataTable().destroy();
                            }
                            if ($.fn.DataTable.isDataTable('#activity_table')) {
                                $('#activity_table').DataTable().destroy();
                            }
                            if ($.fn.DataTable.isDataTable('#mfa_table')) {
                                $('#mfa_table').DataTable().destroy();
                            }
                            $('#groups_table').DataTable({"ajax": "/_get_groups"});
                            $('#policies_table').DataTable({"ajax": "/_get_policies"});
                            $('#mfa_table').DataTable({"ajax": "/_get_mfa"});
                            $('#activity_table').DataTable({"ajax": "/_get_activity"});
                        }
                    });
                    e.preventDefault();
                });
            });
        </script>
        <script>
            $(document).ready(function () {
                $('#groups_table').off().on('init.dt', function () {
                    $('#groups_table tbody').on('click', 'td', function () {
                        var table = $('#groups_table').DataTable();
                        var data = (table.cell(this).data());
                        console.log(data);
                    });
                });
            });
        </script>
    
This discussion has been closed.