Web Analytics Made Easy -
StatCounter InnerText returns undefined - CodingForum

Announcement

Collapse
No announcement yet.

InnerText returns undefined

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • InnerText returns undefined

    The following piece of code works as required

    <div class="shop-item col">
    <span class="shop-item-title">CSS3</span>
    <img class="shop-item-image" src="css3.jpg">
    <div class="shop-item-details">
    <span class="shop-item-price">$14.99</span>
    <button class="btn btn-primary shop-item-button"type="button">ADD TO CART</button>
    </div>
    </div>


    Why does this piece gives the following error

    <div class="shop-item col card rounded-0 img-thumbnail">
    <h3 class="shop-item-title card-title text-center pinkbg">MARTHAS</h3>
    <img class="shop-item-image img-fluid" src="images/tshirt-book.jpg" alt="Card image cap">
    <div class="shop-item-details">
    <div class="card-footer text-center">
    <span class="shop-item-price">$12.99</span>
    <button class="btn btn-success shop-item-button" type="button">BUY NOW!</button>
    </div>
    </div>
    </div>
    </div>


    cart.js:x Uncaught TypeError: Cannot read property 'innerText' of undefined
    at HTMLButtonElement.addToCartClicked (cart.js:x)

    function addToCartClicked(event) {
    var button = event.target
    var shopItem = button.parentElement.parentElement

    var title = shopItem.getElementsByClassName('shop-item-title')[0].innerText
    console.log(title);
    var price = shopItem.getElementsByClassName('shop-item-price')[0].innerText
    var imageSrc = shopItem.getElementsByClassName('shop-item-image')[0].src
    addItemToCart(title, price, imageSrc)
    updateCartTotal()
    }


  • #2
    Hi, I guess identation to these sources will show you why:
    HTML Code:
    <div class="shop-item col">
             <span class="shop-item-title">CSS3</span>
             <img class="shop-item-image" src="css3.jpg">
             <div class="shop-item-details">
                      <span class="shop-item-price">$14.99</span>
                      <button class="btn btn-primary shop-item-button"type="button">ADD TO CART</button>
             </div>
    </div>
    HTML Code:
    <div class="shop-item col card rounded-0 img-thumbnail">
             <h3 class="shop-item-title card-title text-center pinkbg">MARTHAS</h3>
             <img class="shop-item-image img-fluid" src="images/tshirt-book.jpg" alt="Card image cap">
             <div class="shop-item-details">
                      <div class="card-footer text-center">
                               <span class="shop-item-price">$12.99</span>
                               <button class="btn btn-success shop-item-button" type="button">BUY NOW!</button>
                      </div>
             </div>
    </div>
    Instead of giving div.shop-item, this javascript will instead give you div.shop-item-details
    Code:
    var shopItem = button.parentElement.parentElement
    The next javascript line however:
    Code:
    var title = shopItem.getElementsByClassName('shop-item-title')[0].innerText
    is presuming there's a .shop-item-title inside shopItem.
    Last edited by hdewantara; Jul 8, 2020, 08:12 PM. Reason: fine-tuning 2

    Comment


    • #3
      InnerText is SUPPOSED to be IE specific though it is somewhat cross-browser supported...

      What you probably want is textContent, not innerText, though IE 8/earlier don't support it. NOT that in 2020 you should be sending any of your scripting to legacy IE.

      That said that TRAIN WRECK of non-semantic markup with endless pointless presentational classes for nothing, Is a disaster... that your code also appears to have no scripting off graceful degradation is an accessibility violation... after the Supreme Court refused to hear Domino's case you REALLY should be focusing on making whatever this is work without JavaScript via normal form submission FIRST, THEN and only then enhance it with JavaScript.

      Oh, also beware that event.target is often NOT the button as child elements and sometimes parents can trigger the event. You should probably be using Event.currentTarget instead.

      Also if you have multiple var in a row, comma delimit and indent instead of saying var on each and every blasted one of them.... and for the love of Christmas do NOT omit your semi-colons.

      -- edit -- Oops, I see the big problem! You're doing .parentElement.parentElement but your second markup has an extra DIV. As such the DOM walking is broken. In the latter case it's pointing at .shop-item-details instead of .shop-item because you have that extra DIV in there.

      Just part of why slopping out non-semantic markup with likely endless pointless DIV for nothing is bad practice. Let's see... best bet would be to parent walk until class match.

      This is more likely to work:

      Code:
      function addToCartClicked(event) {
          var
              shopItem = event.currentTarget.parentElement;
          while (!shopItem.classList.contains('shop-item')) {
              shopItem = shopItem.parentElement;
          }
          var
              title = shopItem.querySelector('.shop-item-title').textContent,
              price = shopItem.querySelector('.shop-item-price').textContent,
              imageSrc = shopItem.querySelector('.shop-item-image').src;
          console.log(title);
          addItemToCart(title, price, imageSrc)
          updateCartTotal()
      }
      Since button would only have been used once, don't even waste a variable on it.

      That while loop climbing the DOM tree should work regardless of how many pointless/stupid DIV for nothing you slop into it.

      What do I mean by that? I'd have to see it live, but I very much doubt there's ANY reason for the code of that to be anything more than:

      Code:
      <div class="shopItem">
        <h3>MARTHAS</h3>
        <img src="images/tshirt-book.jpg" alt="Card image cap">
        <span>$12.99</span>
        <button type="button">BUY NOW!</button>
      <!-- .shopItem --></div>
      Just whatever derpy framework or system you're working with was created by people unqualified to write a single line of HTML. Hell, if it's scripting only functionality none of this even belongs in your HTML... but that's clearly one of your bigger problems, the bad JS with no scripting off graceful degradation.

      As I've told people for near on a decade and a half. If you can't make a page users can do things like order products with without resorting to JavaScript, you likely have ZERO business adding JavaScript to said page in the first place.
      Last edited by deathshadow; Jul 8, 2020, 11:20 PM.
      I'll kill you and your dreams tonight, begin new life.
      Bleed your death upon me, let your bloodline feed my youth.
      https://cutcodedown.com

      Comment


      • #4
        Hi Deathshadow
        Many thanks for the advice, I will take it on board.
        Although the code submitted is just for learning purposes and will not be going live at all.

        I have another issue perhaps you could help with.
        At the end of the following code I would like to call a function to validate a file type,
        if the function returns false display the error until the a proper file is chosen.
        If the function returns true continue to the confirmation alert message.

        function validate(){

        const myname = document.getElementById('myname');
        const email = document.getElementById('email');
        const filename = document.getElementById('filename');

        if(myname.value == ""){
        myname.nextElementSibling.innerHTML="Please include a name";
        return false;
        }
        if(email.value == ""){
        email.nextElementSibling.innerHTML="Please include an email address";
        return false;
        }
        if(filename.value == ""){
        filename.nextElementSibling.innerHTML="Please include an image";
        return false;
        }
        // call function here
        checkextension();

        alert("Thank you!");
        return true;
        }
        function checkextension() {
        var file = document.querySelector("#filename");
        if ( /\.(jpe?g|png|gif)$/i.test(file.files[0].name) === false ) { alert("not an image!"); }
        }

        I tried to just run the code (before the the alert above) without the function as follows, and was surprised to find that it didn't work.


        if ( /\.(jpe?g|png|gif)$/i.test(file.files[0].name) === false ) {
        filename.nextElementSibling.innerHTML="Not an image";
        return false;


        Comment


        • #5
          This is 2020, not a single line of that is JavaScript's job. Your various "check for empty" should be handled via HTML 5's "required" attribute, and the file type should be set using the "accept" attribute with mime-types.

          What you have there is a poster child for "JS for nothing". Particularly when client-side validation cannot ever be trusted and you have to do it all over again server-side.

          A typical (and well formed) form for something like that being:

          Code:
          <form action="whatever.php" id="userImageUpload">
              <h2>Describe this form</h2>
              <fieldset>
                  <label>
                      Username:<br>
                      <input type="text" name="username" required><br>
                  </label><label>
                      E-Mail:<br>
                      <input type="email" name="email" required><br>
                  </label><label>
                      Image to Upload:<br>
                      <input
                          type="file" name="image" required
                          accept="image/gif, image/jpeg, image/png, image/bmp"
                      ><br>
                  </label>
                  <button>Submit</button>
              </fieldset>
          </form>
          Not a lick of JavaScript required... and whilst e-mail formatting check and required are "new", the "accept" attribute has been around just as long as <input type="file">

          Don't use JS for things HTML and CSS can do without assistance.

          JS for nothing and your scripts for free. That ain't workin', that's not how you do it. Lemme tell ya, these guys ARE dumb. I want my, I want my, I want my PHP.
          Last edited by deathshadow; Jul 14, 2020, 08:58 PM.
          I'll kill you and your dreams tonight, begin new life.
          Bleed your death upon me, let your bloodline feed my youth.
          https://cutcodedown.com

          Comment

          Working...
          X