i had the same problem after removing the defer attribute that @tdm talked about. i solved this simply by adding an domcontentloaded event listener.

document.addeventlistener("domcontentloaded", function () {
    new chart(ctx, {...});


had this same problem however removing defer attribute made other elements not to work in my laravel application. so i allowed defer on the app.js script and used the bellow suggested by @jakub to get it loaded after the dom element.

    function () {
        new chart(...);


this may be the most frustrating (bug/feature/problem) i have ever come accross and got me stuck for a few days, but because my boss doesn't take no for an answer and i hate giving up, i finally managed to solve it. the answer thought me something about html and javascript i never knew:

the answer:

in the <head></head> of your html file you need to change the way bootstrap call's it's app.js from this:

<script src="{{ asset('js/app.js') }}" defer></script>

to this:

<script src="{{ asset('js/app.js') }}"></script>

note the missing defer tag.

the explanation:

you may be wondering, what does the defer tag do? and to answer that i give you this small snippet:



  <script src="" defer></script>

  <p id="p1">
    hello world!



it simply stops the browser from loading/running the script until the site has been completely parsed. in the above example the script we call contains the following code:


basically telling your browser to send an alert with the contents of whatever is inside the p tags. without the defer tag, the script would fail because it would be run before the p tags get parsed by the browser, and javascript can only work with what the browser already parsed.

as far as i found, removing the defer tag doesn't break anything in bootstrap, so i don't know why it even has a defer tag.

i'm also not quite sure why this would be a problem for chart.js, if anyone knows i would love to hear it.

Related Query

More Query from same tag