Rails - DataTables (imported via CDN) shows 'Not a function' until refreshed

Rails - DataTables (imported via CDN) shows 'Not a function' until refreshed

cratagcratag Posts: 10Questions: 3Answers: 0

Hello I have imported DataTables via CDN. Here's the code I have in my genes.html.erb

<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.js"></script>
<script type="text/javascript">
document.addEventListener("turbolinks:load", function () {
  $('#myTable').DataTable();

});
</script>

On first show up, the console logs:

VM8:3 Uncaught TypeError: $(...).DataTable is not a function
    at HTMLDocument.<anonymous> (<anonymous>:3:17)
    at Object../node_modules/turbolinks/dist/turbolinks.js.e.dispatch (turbolinks.js:75)
    at r.notifyApplicationAfterPageLoad (turbolinks.js:994)
    at r.visitCompleted (turbolinks.js:1007)
    at r.complete (turbolinks.js:782)
    at r.<anonymous> (turbolinks.js:812)
    at turbolinks.js:862

after a refresh, it works perfectly.

but obviously I'd like it to work before I refresh.

I've tried some things with no avail. Here's my post on StackOverflow

If there's something else I can add, let me know

This question has an accepted answers - jump to answer

Answers

  • colincolin Posts: 15,112Questions: 1Answers: 2,583

    It would be worth looking to see where you're loading jQuery. This needs to be before DataTables. If it loads after, you would get an error like this.

    Colin

  • cratagcratag Posts: 10Questions: 3Answers: 0

    It is loaded via webpacker in Rails 6.

    // app/javascript/packs/application.js
    import Rails from "@rails/ujs"
    import Turbolinks from "turbolinks"
    import * as ActiveStorage from "@rails/activestorage"
    import "channels"
    
    require("jquery");
    
    //import BOOTSTRAP SCSS & JS
    import 'bootstrap'
    import "../css/site"
    import '@popperjs/core'
    
    //Theme static JS & CSS import
    // I've removed most of the theme.js document as it had many errors in the console about the device used (e.g.: android, ios, firefox, ie, etc.)
    // In case needed, backup the file with the original repo. - The page worked, but gave 6 errors (and 6 jquery parsing errors)
    document.addEventListener("turbolinks:load", require("../js/theme"));
    document.addEventListener("turbolinks:load", require("../css/theme"));
    
    // font awesome
    require("@fortawesome/fontawesome-free/js/all.min.js")
    
    //Owl Carousel
    import "../js/owlcarousel"
    
    //tippy - On hover box from plants individual page
    import tippy from 'tippy.js';
    import 'tippy.js/dist/tippy.css';
    import 'tippy.js/themes/light-border.css'
    import 'tippy.js/themes/translucent.css'
    window.tippy = tippy;
    
    Rails.start()
    Turbolinks.start()
    ActiveStorage.start()
    

    and

        // config/webpack/environment.js
        const { environment } = require('@rails/webpacker')
    
        const webpack = require('webpack')
    
    
        environment.plugins.append("Provide", new webpack.ProvidePlugin({
          $: 'jquery/src/jquery',
          jQuery: 'jquery/src/jquery',
          Popper: ['@popperjs/core', 'default']
        }))
    
        module.exports = environment
    
  • cratagcratag Posts: 10Questions: 3Answers: 0

    a kind soul made a Jfiddle for me, when I asked for help: https://jsfiddle.net/bogatyr77/dxrmnw0g/1/

    on first show, it returns the same error:

    "jQuery.Deferred exception: $(...).DataTable is not a function", "@https://fiddle.jshell.net/bogatyr77/dxrmnw0g/1/show/?editor_console=:229:17
    mightThrow@https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js:3557:29
    resolve/&lt;/process&lt;@https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js:3625:12
    ", undefined
    "<a class='gotoLine' href='#159:17'>159:17</a> TypeError: $(...).DataTable is not a function"
    

    and works after first refresh.

    I'm completely lost.

    I'm using Ubuntu 20.04 - maybe that makes a difference?

    This JFIDDLE sometimes works and some others doesnt

  • kthorngrenkthorngren Posts: 20,142Questions: 26Answers: 4,736
    Answer ✓

    Seems like there is a timing issue with how you are loading the datatables.js in the init() function and when the document.ready() function runs. I used settimeout() to introduce a slight delay before initializing Datatables.
    https://jsfiddle.net/sonzctye/1/

    I'm not familiar with the method you are using in init(). But if there is a callback you can use when its complete then the settimeout delay would be unnecessary. This doesn't seem to be a Datatables specific issue as there doesn't seem to be an issue if the datatables.js is loaded normally as in this example:
    https://jsfiddle.net/sonzctye/2/

    You might find suggestions on Stack Overflow or other resources.

    Kevin

  • cratagcratag Posts: 10Questions: 3Answers: 0

    Well adding a timeout does the trick. Thank you very much.

    It happened before I used the init() function - as someone helped me out in my Stack Overflow thread.

    It might not be a DataTables issue, but it happens both in my Rails app and in the jsfiddles provided - so its weird.

This discussion has been closed.