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