Error accessing header when loading languages from remote url

Error accessing header when loading languages from remote url

danb1974danb1974 Posts: 3Questions: 1Answers: 0

Hello,

Sample code which breaks because of the language being loaded from external url. Something goes very wrong with the header() call. This worked in 1.x

var table = new DataTable('#example', {
  language: {
    url: "https://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/German.json"
  }
});

table.columns().every(function() {
  console.log(this.header().textContent)
});

Demo: https://live.datatables.net/simocufu/1/edit?js,console,output

Comment the url and it works

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 20,993Questions: 26Answers: 4,887

    The language.url docs state this:

    Note that when this parameter is set, DataTables' initialisation will be asynchronous due to the Ajax data load. That is to say that the table will not be drawn until the Ajax request has completed. As such, any actions that require the table to have completed its initialisation should be placed into the initComplete callback.

    Move your code into initComplete.

    Kevin

  • danb1974danb1974 Posts: 3Questions: 1Answers: 0

    Thanks (what threw me off is that it worked in 1.x)

    How should this be done in real life? The entire app requires the table to be initialized and I have a custom component over it like below but a constructor can't be async

    Should I move the initialization to another function and make that async, than await in callers...?

    For now I've hacked it by loading translations in a separate sync ajax call, not very nice

    // called from inside the app whenever a table is enriched with datatable
    class MyDataTableWrapper {
      constructor () {
        new DataTable({language{url}}) // async due to url but can't because in constructor
      }
    
      function1() {} // do something with the table
      functionN() {} // do something else with the table
    }
    
  • allanallan Posts: 62,858Questions: 1Answers: 10,344 Site admin
    Answer ✓

    what threw me off is that it worked in 1.x

    Really surprised by that. language.url has always made the initialisation of the table async. Perhaps there was just enough of a code change to trigger a difference with how the columns API worked. It was a fluke that it worked in 1.x though!

    The ready() function is a good way to work with sync / async table initialisation:

    // called from inside the app whenever a table is enriched with datatable
    class MyDataTableWrapper {
      public dt;
    
      constructor () {
        this.dt = new DataTable({language{url}})
      }
     
      function1() {
        this.dt.ready(function () {
          // do something with the table
        });
      }
    }
    

    With ready() if the table is ready, it will execute the function immediately. If the table is not yet ready, it will wait until it becomes ready and then execute it.

    The alternative is what you have done and get the language information up front and load it in using language which would allow the initialisation of the table to be synchronous.

    Allan

  • danb1974danb1974 Posts: 3Questions: 1Answers: 0

    (Indeed, strange how the code worked apparently without a hitch for years on 1.x despite not waiting for the table to be ready)

    Thanks for the "ready" ideea, might just be what I need if at some point sync $.ajax calls will no longer work

Sign In or Register to comment.