DOM appendChild issues

var node = document.createElement("li");
node.appendChild(document.createTextNode("item"));

list = document.getElementsByClassName("itemList");
list.appendChild(node);

I’m reworking a JS project that I had trouble with in the past and this is giving me quite the hassle. My inspector keeps giving me errors that appendChild is “not a function” or “cannot call method ‘appendChild’ of null”.

Even if I copy an example from somewhere else, I get the same error. This is just a test, but eventually I wan’t to be able to append array items to an unordered shopping list.

That’s probably from list.appendChild(node) if the page has nothing with class itemList

My index.html has <ul class="itemList">
and the script file to my script.js is at the bottom of the body.

Are the DOM calls occurring after DOMContentLoaded event i.e. inside an event handler?

I haven’t included any event handlers yet. Aside from the array objects and a couple functions I used to calculate the price total, that’s all that I have in my script file. I tried starting over from scratch just so I could focus the problem, but it seems to just be that one appendChild line.

Any DOM calls must be made after DOMContentLoaded - just wrap your code in

document.addEventListener("DOMContentLoaded", function(event) {
// your code here
})

https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded#Example

I tried wrapping everything in my script document and also just wrapping the the DOM calls. For both, everything else on the page showed as normal, but I’m still getting errors saying that appendChild(node) isn’t a function.

Please post the entire html and js if possible

(function() {

    var apple = {
          name: "Apple",
          price: 0.50,
      };

      var walnut = {
          name: "walnut",
          price: 0.20
      };

      var spinach = {
          name: "spinach",
          price: 1.30
      };

      var cherries = {
          name: "cherries",
          price: 1.40
      };

      var vinegarette = {
          name: "vinegarette",
          price: 1.10
      };

    var cart = [apple, walnut, spinach, cherries, vinegarette];

    total = [];


    function print() {
        cart.forEach(function(i){
            console.log(i.name);
            console.log("$" + i.price);
        });
    }

    function getSum() {

      cart.forEach(function(i){
      total.push(i.price);
      });

      for (var i = 0; i < total.length; i++) {
          sum = total.reduce(function(a, b) {return a + b;}, 0);
          }
      console.log("Total: " + sum);
    }  


    print();
    getSum();



    var node = document.createElement("li");
    node.appendChild(document.createTextNode("item"));

    list = document.getElementsByClassName("itemList");
    list.appendChild(node);
    
})

I just tried placing everything inside of an IIFE function and that worked! Now I just need to to do the rest.

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>Shopping Cart Assignment Redone</h1>
    <h3>Sub Heading!</h3>
    
    <div class="cartContent">
        <h4>Items In Cart</h4>
        <ul class="itemList">
        
        </ul>
        <p>Total: </p>
    </div>
    
    
    <script src="script.js"></script>
</body>    
</html>

getElementsByClassName returns a collection on which appendChild cannot be called

That makes sense. So instead I would have to do something like
getElementByID("uniqueID");
right?

There are a few choices - you can iterate over the pseudoarray returned by getElementsByClassName - I like querySelector and querySelectorAll because they support CSS selector expressions e.g. document.querySelector(".itemList").appendChild(node)

I’ll try that. Thanks for your help, so far!