Memory leak with datatable child rows

Memory leak with datatable child rows

toniux79toniux79 Posts: 23Questions: 7Answers: 0
edited July 2017 in Free community support

Hello,

I have a main datatable with child rows, and each child row has its own datatable.

I use the function row().child.remove() in order to close the child rows, however the memory used by my navigator (Chrome) is getting bigger and bigger every time I open and close a child row.

Do you have any idea to help me to solve this problem please ?

Note that I use Ajax (JSON source) for the main and the childs datatables.

HTML code for the main datatable :

<table id="tableProcedure" class="display compact" cellspacing="0" width="100%">
        <thead>
            <tr>
                <th>Col 1</th>
                <th>Col 2</th>
                <th>Col 3</th>
                <th>Col 4</th>
            </tr>
        </thead>
 </table>

Javascript code :

    var tabProc = $('#tableProcedure').DataTable(
        {
            ajax: {
                url: "JSON/PROCEDURE.json",
                dataSrc: ""
            },

            columns: [
            { data: "P_OBJ"},
            { data: "P_PDT"},
            { data: "P_ACT_C"},
            {
                data: null,
                orderable: false,
                defaultContent: '',
                className: "details-control-proc"
            }
            ]
        }
    );


    function formatProcedureFils ( rowData ) {
        var div = $('<div/>');

        $.ajax( {
            url: '../detailsProc.php',
            dataType: 'html',
            success: function ( htmlReturn ) {
                div.html( htmlReturn );

                div.find('table').DataTable(
                {
                    ajax: {
                        url: "JSON/PROCEDURE-FILS.json",

                        dataSrc: function ( json ) {                            
                          return json;
                        }
                    },

                    columns: [
                    { data: "P_PRESTL" },
                    { data: "P_DELMAX" }
                    ]
                });

            } 
        } );

        return div;
    }
    

    $('#tableProcedure tbody').on('click', 'td.details-control-proc', function () {
            var tr = $(this).closest('tr');
            var row = tabProc.row( tr );

        if ( row.child.isShown() ) {
            // This row is already open - close it
            row.child(true).remove();
            tr.removeClass('shown');
        }
        else {
            // Open this row
            row.child( formatProcedureFils(row.data()) ).show();
            tr.addClass('shown');
            }
    });

Thank you for your help.
Anthony

This question has an accepted answers - jump to answer

Answers

  • rduncecbrduncecb Posts: 125Questions: 2Answers: 28
    edited July 2017 Answer ✓

    The leak is in your code. Your formatProcedureFils function creates a datatable each time it is executed. Because DataTables internally keeps a list all DataTables created you must call destroy on it when you are done with it or it will hang around in memory. Your code does not clean up DataTable instances that are no longer needed.

  • toniux79toniux79 Posts: 23Questions: 7Answers: 0

    Thank you for your answer.

    Yes I create a new datable for each child row. I thought the API row().child.remove() would also remove these datatables, but no..

    I am now trying to use the destroy() function as suggested but not effect for the moment :

        $('#tableProcedure tbody').on('click', 'td.details-control-proc', function () {
                var tr = $(this).closest('tr');
                var row = tabProc.row( tr );
                
            if ( row.child.isShown() ) {
                // This row is already open - close it
                var tables = $('.dataTable').DataTable();
                tables.table('.child').destroy();
    
                row.child(true).remove();            
               
                tr.removeClass('shown');
            }
            else {
                // Open this row
                row.child( formatProcedureFils(row.data()) ).show();
                tr.addClass('shown');
                }
        });
    

    I keep trying ...

  • toniux79toniux79 Posts: 23Questions: 7Answers: 0
    edited July 2017

    It works !

    I added "true" parameter on the destroy function.

        $('#tableProcedure tbody').on('click', 'td.details-control-proc', function () {
                var tr = $(this).closest('tr');
                var row = tabProc.row( tr );
                
            if ( row.child.isShown() ) {            
                // Remove the child datatable and child rows
                var tables = $('.dataTable').DataTable();
                tables.table('.child').destroy(true);
                
                row.child(true).remove();
                tr.removeClass('shown');
            }
            else {
                // Open this row
                row.child( formatProcedureFils(row.data()) ).show();
                tr.addClass('shown');
                }
        });
    
This discussion has been closed.