Search code examples
javascripthtmlmodulewindow

window.np is undefined even though it appears in console when window is printed


I've been trying to fix this one issue I ran into but have no idea why my code is wrong. I have this module I made using javascript for NPM. I just converted that npm to HTML syntax and imported that module into this HTML file.

But when I try to access the items using "window.np"(window is how I save those files into the user's computer), it says "window.np" is undefined. I have no idea why it says this because when I just do console.log(window), I can see 'np' as one of the attributes. But I am still unable to access it.

This is the output when I do "console.log(window)".

enter image description here

This is the expanded version of the picture above.

enter image description here

<!DOCTYPE html>
<html>
    <body>
        <script type="module" src="https://unpkg.com/[email protected]/src/html/index.js">
        </script>

        <script>
            console.log(window)
            console.log(window.np)
        </script>
    </body>
</html>

Solution

  • Scripts included as an ES6 module via type="module" are actually deferred by default (MDN), meaning that the numpy-matrix-js script will run after the inline script.

    The fix for this is simple: you need to defer the inline script's execution to after the module's. One way is the defer attribute, but since that only works on external scripts, you'll need to put it in a separate file. The other method would be to listen for DOMContentLoaded:

    <!DOCTYPE html>
    <html>
        <body>
            <script defer type="module" src="https://unpkg.com/[email protected]/src/html/index.js">
            </script>
    
            <script>
                window.addEventListener("DOMContentLoaded",function(){
                    console.log(window)
                    console.log(window.np)
                });
            </script>
        </body>
    </html>
    

    See How to defer inline Javascript? for more info.

    As for why it displays in the console, I'm guessing that the fancy object browser looks up the properties when you click on it (ie. after the module has ran), not when its logged.