Search code examples
javascripthtmlnode.jswebfile-not-found

Why my function middleContainer is undefine - JS modules


I tested my JS code with Node and the import keyword gets flagged. I have read and watch videos on how to import vars,etc from other JS files.

I believe my syntax is correct, but I do not understand why it does not work properly.

Here is my HTML code:

<!DOCTYPE html>

<html>

    <head>
        <title>JAPC</title>

        <meta charset="utf-8"/>

        <!-- CSS -->
        <link rel="stylesheet" type="text/css" href="./CSS/page_structure.css">
        <link rel="stylesheet" type="text/css" href="./CSS/navstack_structure.css">
        <link rel="stylesheet" type="text/css" href="./CSS/jpdc_structure.css">
        <link rel="icon" href="./Images/Page_Imgs/favicon-16x16.png">

        <!-- JS -->
        <script type="module" src="./JS/page_structure.js"> </script>

    </head>

    <body onload="middleContainer()">
        <div> <!--DIV 1-->
            <div id="top_container">
                <!--DIV 1.1 | Header-->
                <h1>Header</h1>
            </div>
            <!-- --------------------- -->
            <div id="middle_container">
                <!--DIV 1.2 | Body-->
            </div>
            <!-- --------------------- -->
            <div id="bottom_container">
                <h1>Footer</h1>
            </div>
        </div>
    </body>
</html>

Here is my JS code:

/*
    Page Structure
*/
import { top_container_config, middle_container_config, bottom_container_config} from './page_structure_config.js';

//------------------------------------------------------------------------------

function createDOMelement(element_, attributues_){
  var elem_ = document.createElement(element_);
  var k;
    for (k in attributues_){
      elem_.setAttribute(k,attributues_[k]);
  }
  return elem_;
}

//------------------------------------------------------------------------------
function topConainter(){
  var _container = "top_container";

}

//------------------------------------------------------------------------------

function middleContainer(){
  var _container_ID = "middle_container";
  var _columns = [];
  var _navVar;
  var _nv_items =[];

  //Columns
  for(var col = 0; col < middle_container_config.mc_columns.num; col++){
    _columns.push(createDOMelement("div",middle_container_config.mc_columns._DOM_));
  }

  //My Nav Var
  _navVar =  createDOMelement("div", middle_container_config.nav_stack._DOM_);

  //Inside my Nav Var
  for(var nv_i = 0; nv_i < middle_container_config.nav_stack_items.num; nv_i++){
    _nv_items.push(createDOMelement("div",middle_container_config.nav_stack_items._DOM_));
  }


  //JOIN ALL ELEMENT  - Inside OUt
  for (var a =0; a<_nv_items.length; a++){
    _navVar.appendChild(_nv_items[a]);
  }

  //Append NavVar to first column of the middle_container
  _columns[0].appendChild(_navVar);

  //add to DOM
  for(var b=0; b<_columns.length; b++){
    document.getElementById(_container_ID).appendChild(_columns[b]);
  }

  console.log(document.getElementById(_container_ID));

}

//------------------------------------------------------------------------------

function bottomContainer(){
  var _container = "bottom_container";

}

Here is picture of my Node output:

I run my node command as the following:

node page_structure.js

enter image description here


Solution

  • The problem is that your onload listener is not aware of middleContainer function because middleContainer is not defined on global scope.

    One of the option is to just define the function on global scope.

    // in page_structure.js
    // middleContainer defined on module scope
    function middleContainer(){
      var _container_ID = "middle_container";
      ...
    }
    // middleContainer defined global scope
    window.middleContainer = middleContainer;
    

    Then <body onload="middleContainer()"> should no longer complain about middleContainer being undefined and should run the middleContainer function.

    Another option is to add the onload event listener to your module. Instead you can remove the onload attribute on the <body> tag and defined the onload event as follows

    // in page_structure.js
    function middleContainer(){
      var _container_ID = "middle_container";
      ...
    }
    // define the listener with your module scoped function to a global event listener
    window.onload = middleContainer;