typeerror : row is undefined with 1.10beta

typeerror : row is undefined with 1.10beta

mihomesmihomes Posts: 150Questions: 19Answers: 0
edited February 2014 in TableTools
Just loaded up the most current 1.10 and making sure to switch all code to the new formats... I am running across a 'TypeError: row is undefined' for the following. Funny thing is my table loads exactly as expected, but the error is thrown and the processing indicator is stuck. You can see my original code commented out.

[code]
"drawCallback": function() {
// show in new row and add active class if necessary
$('#datatable > tbody > tr').each(function() {
var tr = $(this);
var id = tr.attr('id');
var idclass = tr.attr('class');
//var data = dt.fnGetData( tr );
var data = dt.row(tr).data();

//create row
if (typeof data !== 'undefined') {
//dt.fnOpen( tr, format(data), ''+data.DT_RowId+'-info' );

dt.row(tr).child( format(data), ''+data.DT_RowId+'-info' ).show();

}

$('#datatable .'+id+'-info').parents('tr').addClass(idclass);

// add active if necessary
if ( $.inArray(id, selected) !== -1 ) {

tr.addClass('active');
// class for new row
$('#datatable .'+id+'-info').addClass("active");

var checkbox = tr.find('.checkboxes');
$(checkbox).attr("checked", true);
}
});
}
[/code]

Replies

  • allanallan Posts: 55,815Questions: 1Answers: 8,815 Site admin
    What is `dt` in this context?

    In the callback functions, to access the API you will typically want to do:

    [code]
    var api = this.api();
    [/code]

    Allan
  • mihomesmihomes Posts: 150Questions: 19Answers: 0
    edited February 2014
    [code] dt = $('#datatable').DataTable({...... [/code]

    I just took another look at the docs and it would appear in this case dt.row(tr)... and api.row(tr)... are the same as I define dt... correct?

    Using firebug in firefox... console is reporting the error and references line 5 of jquery-1.10.2.min.js for it, however, these are the only instances in my js where row is used.
  • allanallan Posts: 55,815Questions: 1Answers: 8,815 Site admin
    > I just took another look at the docs and it would appear in this case dt.row(tr)... and api.row(tr)... are the same as I define dt... correct?

    Sort of :-). You would think so, but the trap you've fallen into here is that `drawCallback` is executed before the table initialisation completes! Therefore from:

    [code]
    dt = $('#datatable').DataTable({......
    [/code]

    The variable `dt` has not yet been assigned - since the `DataTable()` function is still running!

    So in this case, `dt` is undefined and you get the error.

    Generally speaking in callbacks I would recommend using the `this.api()` form, since that will give you the API regardless of if the API has completed its initialisation or not.

    The second example here shows the recommended form: http://next.datatables.net/reference/option/drawCallback

    Allan
  • mihomesmihomes Posts: 150Questions: 19Answers: 0
    edited February 2014
    Allan,

    I went ahead and changed the my code using :

    [code]
    var api = this.api();
    [/code]

    and then replacing, in my examples, dt with api. I am now getting a 'TypeError: this.api is not a function' error message using it.

    [code]
    "drawCallback": function() {
    $('#datatable > tbody > tr').each(function() {
    var tr = $(this);
    var id = tr.attr('id');
    var idclass = tr.attr('class');
    //var data = dt.fnGetData( tr );
    // set api
    var api = this.api();
    var data = api.row(tr).data();

    //create new row
    if (typeof data !== 'undefined') {
    //dt.fnOpen( tr, format(data), ''+data.DT_RowId+'-info' );

    api.row(tr).child( format(data), ''+data.DT_RowId+'-info' ).show();

    }

    $('#datatable .'+id+'-info').parents('tr').addClass(idclass);

    // add active if necessary
    if ( $.inArray(id, selected) !== -1 ) {

    tr.addClass('active');
    // class for new row
    $('#datatable .'+id+'-info').addClass("active");

    var checkbox = tr.find('.checkboxes');
    $(checkbox).attr("checked", true);
    }
    });
    }

    [/code]
  • mihomesmihomes Posts: 150Questions: 19Answers: 0
    I noticed in the example you pointed me earlier you are using $('#example').dataTable( { where I am using the new $('#example').DataTable( {...

    From what I can tell I should be using DataTable as I am, but perhaps I am mistaken on this.
  • allanallan Posts: 55,815Questions: 1Answers: 8,815 Site admin
    `this` in the context you have used `this.api()` (i.e. inside an `each` function) is the `tr` element - not the table element.

    Use:

    [code]
    "drawCallback": function() {
    var api = this.api()

    ...
    [/code]

    its also far more efficient since the API instance is only obtained once.

    > I noticed in the example you pointed me earlier you are using $('#example').dataTable( { where I am using the new $('#example').DataTable( {...

    See this section of the documentation for an explanation of the difference between the two: http://next.datatables.net/manual/api#Accessing-the-API (it has no difference in your code above btw).

    Allan
  • mihomesmihomes Posts: 150Questions: 19Answers: 0
    I should have noticed that before, but unfortunately this is not solving the problem... still getting a TypeError : row is undefined

    I am checking the tr and data values in the console and they are properly returned and valid. I also removed a format function I was performing just to make sure that was not the issue and instead show one of my column values in its place.

    The table displays perfectly fine just as expected, but this error keeps showing and in turn the processing notification never disappears from the screen making the page unusable.

    The offending line is [code]api.row(tr).child( data.window_title, ''+data.DT_RowId+'-info' ).show();[/code] and everything looks perfectly fine to me.

    [code]
    "drawCallback": function() {
    // set api variable for use before function
    var api = this.api();

    // show new row and add active if necessary
    $('#datatable > tbody > tr').each(function() {
    var tr = $(this);
    var id = tr.attr('id');
    var idclass = tr.attr('class');
    //var data = dt.fnGetData( tr );
    var data = api.row(tr).data();
    // check values
    console.log(tr);
    console.log(data);

    //create row
    if (typeof data !== 'undefined') {
    //dt.fnOpen( tr, format(data), ''+data.DT_RowId+'-info' );

    //api.row(tr).child( format(data), ''+data.DT_RowId+'-info' ).show();
    //remove format function to make sure and display a column value
    api.row(tr).child( data.window_title, ''+data.DT_RowId+'-info' ).show();

    }

    $('#datatable .'+id+'-info').parents('tr').addClass(idclass);

    // add active if necessary
    if ( $.inArray(id, selected) !== -1 ) {

    tr.addClass('active');
    // class for row
    $('#datatable .'+id+'-info').addClass("active");

    var checkbox = tr.find('.checkboxes');
    $(checkbox).attr("checked", true);
    }
    });
    }
    [/code]
  • allanallan Posts: 55,815Questions: 1Answers: 8,815 Site admin
    I'm not getting an `api.row()` error is a cut down working example here: http://live.datatables.net/EGiC/4/edit . The `console.log( tr )` was slowing my browsers down something horrible for some reason, which is why it is commented out.

    Can you please link to a test case showing the problem.

    Allan
  • mihomesmihomes Posts: 150Questions: 19Answers: 0
    I checked your link and even played around with it to act like my own and had it working fine. The only difference being dom loaded instead of serverside.

    Out of curiosity I modified my own script... removing serverside, changing the "columns" appropriately for dom elements, etc and loaded a few entries in the table. The same error occurs, however, slightly different in its reporting.

    [code]
    TypeError: row is undefined
    if ( row._detailsShow ) {

    http://www.mysite.com/assets/plugins/data-tables-1.10/media/js/jquery.dataTables.js
    Line 7717
    [/code]

    I created an example using dom elements and copied my dom js exactly as I have on my end - same thing happens with the processing indicator stuck, but the table shows as expected. I created a milestone for it at http://live.datatables.net/EGiC/6/

    Maybe you can help me out through this example (I removed a few things, but nothing major and the only difference is the use of serverside. Thanks for the assistance with this Allan.
  • allanallan Posts: 55,815Questions: 1Answers: 8,815 Site admin
    Brilliant! I think I've got it now - or at least I understand the problem, but don't yet have a fix (too late at night!).

    The problem is: `table.find('tbody tr')` in the event handler is getting all `tr` elements, including the already open rows, which really isn't all that useful, since they are 'real' rows - and thus this error is thrown.

    Fix will be to use the DataTables API internally to get the 'real' rows only. I'll try to get that in tomorrow morning.

    Thanks for the test case.

    Allan
  • mihomesmihomes Posts: 150Questions: 19Answers: 0
    Great news! Thanks for taking the time to look into this Allan.
  • allanallan Posts: 55,815Questions: 1Answers: 8,815 Site admin
    Fix is committed here along with a few other things I discovered along the way: https://github.com/DataTables/DataTablesSrc/commit/19a4f46

    The nightly build of DataTables has been updated, and you live example now works:
    http://live.datatables.net/EGiC/8/edit

    Allan
  • mihomesmihomes Posts: 150Questions: 19Answers: 0
    Working fine. Thanks Allan.
This discussion has been closed.