Problem with getting a column average?

Problem with getting a column average?

mk0mk0 Posts: 10Questions: 2Answers: 0

Using the example as per the instructions on this site:

<script>
  var table = $('#example').DataTable();
  var avg = table.column( 1 ).data().average();
</script>

...I'm getting the error:

DataTables warning: table id=datat - Cannot reinitialise DataTable. For more information about this error, please see http://datatables.net/tn/3

Based on the info on the page the error message links to, this is due to two table objects being created. Following the instructions and using table.destroy() I get rid of the error message but getting NaN for average for column of integers.

Here is the debug information:

https://debug.datatables.net/apawen

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 20,309Questions: 26Answers: 4,769

    Unfortunately there is not enough information to help. You have a Datatable using a table with the ID id=datat. That is independent of this table with the ID example: var table = $('#example').DataTable();`

    Maybe you can post more of your javascript code so we can see what you are doing and why the Datatable using id=datat is being initialized more than once.

    Kevin

  • mk0mk0 Posts: 10Questions: 2Answers: 0

    Sorry and thanks so much for kind reply :)

    Below is the Javascript, it's coming from a template that I'm using and then I modified it according to the setup I already had working elsewhere.

    var App = (function () {
      'use strict';
    
      App.dataTables = function( ){
    
        //We use this to apply style to certain elements
        $.extend( true, $.fn.dataTable.defaults, {
          dom:
            "<'row be-datatable-header'<'col-sm-6'l><'col-sm-6'f>>" +
            "<'row be-datatable-body'<'col-sm-12'tr>>" +
            "<'row be-datatable-footer'<'col-sm-5'i><'col-sm-7'p>>"
        } );
    
        //Enable toolbar button functions
        $('#datat').DataTable( {
          dom: 'Blfrtip',
          "lengthMenu": [[15, 30, 50, 100, -1], [15, 30, 50, 100, "All"]],
          "searching": true,
          'language': { search: "", info: "<b>_START_</b> to <b>_END_</b> out of <b>_TOTAL_</b>" },
          dom:  "<'row be-datatable-header'<'col-sm-2'l><'col-sm-4'><'col-sm-4 text-right'B><'col-sm-1 text-right'f>>" +
                "<'row be-datatable-body'<'col-sm-12'tr>>" +
                "<'row be-datatable-footer'<'col-sm-5'i><'col-sm-7'p>>",
            "processing": false,
            
            "serverSide": true,
            "ajax": "server_processing.php",
            'scrollY': '71vh',
            'scrollCollapse': true,
            'deferRender': true,
            'scroller': true,
            'paging': true,
            'type': "POST",
            'responsive': true  
        });
      };
    
      return App;
    })(App || {});
    
    

    In the HTML I'm trying to load it like so


    <script> var table = $('#datat').DataTable(); var avg = table.column( 1 ).data().average(); </script>

    I've also tried the exact variation of the example on this site, which is:


    <script> var table = $('#datat').DataTable(); table.column( 1 ).data().average(); </script>

    In that HTML I'm loading the assets in header:

    assets/lib/datatables/datatables.net/js/jquery.dataTables.js
    //cdn.datatables.net/plug-ins/1.10.16/api/average().js
    
    

    And rest in footer.

    Also maybe it's relevant, I have 1,000,000 rows in the mysql where the data is coming from. I got everything else working just fine, but this I can't figure out it seems.

  • kthorngrenkthorngren Posts: 20,309Questions: 26Answers: 4,769

    My guess is this is executing first:

    <br><script>
      var table = $('#datat').DataTable();
      var avg = table.column( 1 ).data().average();
    </script>
    

    Followed by this code:

    var App = (function () {
      'use strict';
     
      App.dataTables = function( ){
    ....
        //Enable toolbar button functions
        $('#datat').DataTable( {
          dom: 'Blfrtip',
    ....
    

    When the second is executed you are getting the Cannot reinitialise DataTable error.

    That's just a guess without knowing more about how / when everything executes.

    Kevin

  • mk0mk0 Posts: 10Questions: 2Answers: 0

    I tried to change the order but the outcome is exactly the same unfortunately. Do you have any suggestion for how to move forward with this? Better yet, can you point to one code-complete example where somebody is doing this (could not find any online). I think that would be enough to overcome this, to see how it actually does work. Thanks so much for your effort to help! Very much appreciated :)

  • kthorngrenkthorngren Posts: 20,309Questions: 26Answers: 4,769

    Can you post a link to your page?

    Maybe you are calling App multiple times causing the reinitialization error?

    Without seeing the complete code its hard to say what the problem is.

    Kevin

  • mk0mk0 Posts: 10Questions: 2Answers: 0

    I've create a codepen with the html and javascript. The code that I've posted works 100% as expected. It is when the code example for getting the average is introduced, when the error is coming out. In terms of loading the assets, most of it comes from local as comes also the data, so as things would not work anyway, I've also removed style assets, and all the other content from the html. If this is not sufficient, I can post more as needed.

    Here is the code snippet from the example that is causing the problem (note it's not present in the code as I wanted to post something that I've tested and works). I could not find any condition under which the snippet will not cause the above mentioned error and where I can also get the average. It is the second line that creates the error more specifically

    <script>
      var table = $('#datat').DataTable();
      table.column( 1 ).data().average();
    </script>
    
  • mk0mk0 Posts: 10Questions: 2Answers: 0

    What I had done just now is try the code you provided for a separate problem, and it caused the same double loading problem. Then I tried that in my original setup which does not rely on any theme, but just what I downloaded off DataTables.net and works like a charm. So clearly there is something wrong with the way this theme is handling things. But the question still remains the same, how could I overcome it. Still, this gives a sense of relief as I know that the worst case scenario is that I drop the way this theme is doing things, and try to build what I like about it around the native DataTables setup I already had working before.

  • kthorngrenkthorngren Posts: 20,309Questions: 26Answers: 4,769
    Answer ✓

    I tried your codepen but it doesn't seem to work. Anyway, I'm not familiar with how you are initializing your JS by using this:

          $(document).ready(function(){
            //initialize the javascript
            App.init();
            App.dataTables();
          });
    

    I wonder if App.init(); is executing the App.dataTables = function( ) function then App.dataTables(); does it again. To verify you can place console.log() output between these two lines:

      App.dataTables = function( ){
        console.log('initializing DT');
        //We use this to apply style to certain elements
    

    If you see the output twice

    This portion of the code should just give you an API instance of an already initialized Datatable:

    <script>
      var table = $('#datat').DataTable();
      table.column( 1 ).data().average();
    </script>
    

    You can see in this example that I can initialize Datatables with some options and use the above two lines to get the average. No errors.
    http://live.datatables.net/yudapopa/1/edit

    Kevin

  • mk0mk0 Posts: 10Questions: 2Answers: 0

    Thanks a lot Kevin! The example is clear, and highlights what an elegant platform this is. I think that for my own sanity (and those kindly offering their helping hand here in the forum) going forward I use only the non-DataTables part of this theme, and stick with the native version for all the DataTables parts. It seems that it's incredibly easy to do what one desires...I only hit a snag once I moved to the way this theme is handling things.

  • mk0mk0 Posts: 10Questions: 2Answers: 0

    Unfortunately this does not seem to work when server side / ajax is used. It just returns NaN. Here is my javascript:

    $(document).ready(function() {
    
        var table = $('#example').DataTable({
            "serverSide": true,
            "ajax": "server_processing.php",
            "pageLength": 15
        });
    
        var table = $('#example').DataTable();
        var avg = table.column( 1 ).data().average();
    
        console.log(avg);
    } );
    
    

    This is basically a copy of what you had posted (note the example works perfectly in my end as well) with the exception that data is now coming from server side. The column 1 in my mysql is an 'int' so that should not be a problem. Also I noted from the source that it handled cases where the values were strings. Is it possible that as it stands, using this average method is not possible "out-of-the-box" with server side data?

  • kthorngrenkthorngren Posts: 20,309Questions: 26Answers: 4,769
    edited May 2018

    Not sure why you are getting NaN. Would need to see the data. However average() is a client side plugin and would only get the average of the (10 by default) rows being displayed. You would need to calculate the average using your server script and return it to the client via ajax.

    Just to make sure... column( 1 ) refers to the second column in your table.

    Kevin

  • allanallan Posts: 61,723Questions: 1Answers: 10,108 Site admin

    NaN suggests that there is non-numeric data in the column somewhere. Try using console.log( table.column(1).data().toArray() ); and let us know what is shown in your browser's console.

    As Kevin points out though, you'll only get the average of the values that are shown in the table, not the entire data set, since you are using server-side processing.

    Allan

This discussion has been closed.