When last row in table is selected, this.data() is undefined

When last row in table is selected, this.data() is undefined

gleblancgleblanc Posts: 10Questions: 1Answers: 0

Debugger code (debug.datatables.net): oloruz
Error messages shown: this.data() is undefined
Description of problem: When selecting rows and using .every to iterate over them, if the last row is selected, during the callback function this.data() is undefined for the last row.

Answers

  • kthorngrenkthorngren Posts: 14,169Questions: 25Answers: 3,340

    Looks like what you described works here:
    http://live.datatables.net/vacuyixa/1/edit

    Please update my example or provide a link to your page or a test case replicating the issue so we can help debug.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • gleblancgleblanc Posts: 10Questions: 1Answers: 0
    edited August 11

    The only difference between this page (https://datatables.net/examples/api/select_row.html) and my table are the initialization options;

            var tbl = $("#table").DataTable({
                data: data,
                pageLength: 100,
                scrollX: true,
                processing: true,
                "language": {
                    processing: '<i class="fas fa-spinner fa-spin fa-3x fa-fw"></i><span class="sr-only">Loading...</span>'
                },
                columns: [
                    {"data": "boots\\.path"},
                    {"data": "boots\\.version"},
                    {"data": "boots\\.create_time"}
                ]
            })
    

    I'm selecting multiple table rows via the method used in the example on the linked page. If the last table row is in that set, it's data is undefined on a semi-inconsistent schedule. Not sure if this is documentation error or me error, but there's literally no difference between the tables other than I gave this one data through the api.

    I'd prefer not to just post my entire source code here if possible, but below are a few pieces.

    To select a row:

            $('#table tbody').on('click', 'tr', function () {
                $(this).toggleClass('table-info');
            });
    

    Delete rows:

            $('#delete-button').click(function () {
                tbl.rows('.table-info').every(function(idx, tL, rL) {
                    console.log(this.data())
                    var rowData = this.data()
                    $.ajax({
                        url: "n/a",
                        method: "post",
                        data: rowData,
                        statusCode: {
                            200: function(data) {
                                row.remove().draw(false)
                                displayAlert("alert-success", data["Response"], 5000)
                            },
                            400: function(data) {
                                displayAlert("alert-danger", data["Response"], 5000)
                            }
                        }
                    })
                    tbl.rows('.table-info').remove().draw( false );
                })
            });
    

    The above has been tried with various combinations of tbl.row(idx).data() and so on, if the last row is in that set it will be undefined most of the time. I have had it randomly work once or twice, but never consistent, never reproducible with a process.

    EDIT: Small (I think?) addition; I'm using bootstrap 5 datatables, but I didn't think that would effect this sort of thing.

  • gleblancgleblanc Posts: 10Questions: 1Answers: 0

    Additionally, this is always defined, but sometimes this.data() is undefined.

  • colincolin Posts: 12,939Questions: 0Answers: 2,204

    As Kevin said, please can you update his example to demonstrate the problem. We'll need to see your issue to be able to progress this,

    Colin

  • gleblancgleblanc Posts: 10Questions: 1Answers: 0
    edited August 12

    I made a fiddle with literally the same code I have and it works here but not on my site, doesn't make sense.

    also if you are all going to require literally exactly what im doing locally word for word and me to paste random code into my console and stuff, you should probably be able to figure out how to debug the literal code i pasted above.

  • gleblancgleblanc Posts: 10Questions: 1Answers: 0
    edited August 12

    In any event, I think the issue is more closely related to the iteration happening within every, as this.data() within every should not be undefined ever if I am iterating over table rows that I have selected and can see.

    I also just noticed that the first reply fiddle is using the select plugin which im not using which can be seen on the debug page that i had to run to open this topic.

  • gleblancgleblanc Posts: 10Questions: 1Answers: 0

    Not trying to spam thread, can't edit after 15 minutes... but some additional context is that this is always defined, and is the row, but this.data() is sometimes undefined. This is why this seems like a bug and does not make sense.

  • gleblancgleblanc Posts: 10Questions: 1Answers: 0
    edited August 12


    every method returns more than one row for this, the documentation for every doesn't seem to specify this can be the case. The iterator class mentions concatenating the data unless passed a flatten flag, but if I'm iterating over a set of rows, I probably should only receive one at a time. First object shown (above text console message) is this, second object is this.row().data(), third is this.rows().data()

    edit: ("smaller than 0" in the screenshot is a typo on my behalf, it should be '1')
    edit: additionally, i have found that it does not necessarily have to contain the last row in the table, but can be any rows. usually seems to help if there's more than 2 or 3 selected.

  • kthorngrenkthorngren Posts: 14,169Questions: 25Answers: 3,340

    I also just noticed that the first reply fiddle is using the select plugin which im not using which can be seen on the debug page that i had to run to open this topic.

    Only the developers have access to this.

    I suspect the problem is using an ajax call within the loop. Since its an asynchronous call the remove in line 11 is executed at some point after the remove in line 19. Not sure what you are trying to do with the ajax request and the remove() in the success function. I would say this is causing issues with datatables and the undefined.

    however this is all speculation as its hard to say exactly what is happening without seeing the code.

    Kevin

  • gleblancgleblanc Posts: 10Questions: 1Answers: 0
    edited August 12

    I suspect the problem is using an ajax call within the loop.

    The issue happens before the ajax call, so that shouldn't effect it; also, ajax call would be actually removing data from backend, then .remove would remove from table.

    Only the developers have access to this.

    I was able to open it in a different browser on a VM hosted on a separate server which was using a VPN and on a different network. (I cannot tell if this seems snarky or unrealistic, it is not meant to be, I did actually take these steps.)

  • colincolin Posts: 12,939Questions: 0Answers: 2,204

    also if you are all going to require literally exactly what im doing locally word for word and me to paste random code into my console and stuff, you should probably be able to figure out how to debug the literal code i pasted above.

    The problem is if it works for you in a test case, and it works for Kevin's code in his test case, then just looking at the literal code won't help as the code has been proven to work. For us to help you, it would speed the process up if we could debug the code when the problem occurs...

    Colin

  • gleblancgleblanc Posts: 10Questions: 1Answers: 0
    edited August 12

    if we could debug the code when the problem occurs

    right, short of being able to access my internal network that's probably not possible, but either way, rest assured, I am using the code copied from the documentation for this. the documentation for every does not match the behavior of every on occasion. there is a line of code somewhere, I suspect in iterator that is causing multiple rows to be assigned to a single run of every. if you guys are not DT devs, can a dev pleaseeee look at this. Not trying to be disrespectful, I just think that this is genuinely an issue within the API.

  • kthorngrenkthorngren Posts: 14,169Questions: 25Answers: 3,340

    The issue happens before the ajax call, so that shouldn't effect it; also, ajax call would be actually removing data from backend, then .remove would remove from table.

    What does row.remove().draw(false) on line 11 do?

    Actually I think the problem is with tbl.rows('.table-info').remove().draw( false ); being inside the rows().every() loop. So you are deleting rows that you are iterating. Maybe move this statement after the loop so its executed only once. You can see this same behavior of removing rows, while in the loop, in this example:
    http://live.datatables.net/gaxequgu/1/edit

    Kevin

  • gleblancgleblanc Posts: 10Questions: 1Answers: 0

    Actually I think the problem is with tbl.rows('.table-info').remove().draw( false ); being

    You are absolutely correct. I actually thought it was outside the every callback.

Sign In or Register to comment.