kaweki
kaweki

Reputation: 445

TypeError: Cannot read property 'classList' of null

I am getting an error

TypeError: Cannot read property 'classList' of null

I am not really sure what am I doing wrong in manipulating DOM element for each form field. My form field has an stated name and ID of form and each input field has a name and id of the field as well. But I am still getting an error.

What am i doing wrong?

My script:

document.querySelector("#form").addEventListener("submit", function(e){
//create variable for contact form url
var formURL = 'melonForm.php';
//prevent default submission
event.preventDefault();
//define form fields
var melonForm = {
    'firstName'              : document.querySelector('input[name=firstName]').value,
    'lastName'             : document.querySelector('input[name=lastName]').value,
    'companyName'       : document.querySelector('input[name=companyName]').value,
    'companyAddress'       : document.querySelector('input[name=companyAddress]').value,
    'city'       : document.querySelector('input[name=city]').value,
    'state'       : document.querySelector('select[name=state]').value,
    'zipcode'       : document.querySelector('input[name=zipcode]').value,
    'emailAddress'       : document.querySelector('input[name=emailAddress]').value,
    'phoneNumber'       : document.querySelector('input[name=phoneNumber]').value,
}

//define request variable
var formRequest = new Request(formURL, {
    method: 'POST', 
    body: melonForm, 
    headers: new Headers()
});

//fetch
fetch(formRequest)
.then(function(formResponse) {
    return formResponse.json();
  })
.then(function(data) {
    //handle server responses
    if ( ! data.success) {
    //handle error messages
        //handle error message for firstName
        console.log(data);
        if (data.errors.firstName) {
            document.getElementById("firstName").classList.add("has-error");
            document.getElementById("firstName").appendChild('<div class="help-block">' + data.errors.firstName + '</div>');
        }
        //handle errors for lastName
        if (data.errors.lastName) {
            document.getElementById("lastName").classList.add("has-error");
            document.getElementById("lastName").appendChild('<div class="help-block">' + data.errors.lastName + '</div>');
        }
        //handle errors for companyName
        if (data.errors.companyName) {
            document.getElementById("companyName").classList.add("has-error");
            document.getElementById("companyName").appendChild('<div class="help-block">' + data.errors.companyName + '</div>');
        }
        //handle errors for companyAddress
        if (data.errors.companyAddress) {
            document.getElementById("companyAddress").classList.add("has-error");
            document.getElementById("companyAddress").appendChild('<div class="help-block">' + data.errors.companyAddress + '</div>');
        }
        //handle errors for city
        if (data.errors.city) {
            document.getElementById("city").classList.add("has-error");
            document.getElementById("city").appendChild('<div class="help-block">' + data.errors.city + '</div>');
        }
        //handle errors for state
        if (data.errors.state) {
            document.getElementById("state").classList.add("has-error");
            document.getElementById("statea").appendChild('<div class="help-block">' + data.errors.state + '</div>');
        }
        //handle errors for zipcode
        if (data.errors.zipcode) {
            document.getElementById("zipcode").classList.add("has-error");
            document.getElementById("zipcode").appendChild('<div class="help-block">' + data.errors.zipcode + '</div>');
        }
        //handle errors for emailAddress
        if (data.errors.emailAddress) {
            document.getElementById("emailAddress").classList.add("has-error");
            document.getElementById("emailAddress").appendChild('<div class="help-block">' + data.errors.emailAddress + '</div>');
        }
        //handle errors for phoneNumber
        if (data.errors.phoneNumber) {
            document.getElementById("phoneNumber").classList.add("has-error");
            document.getElementById("phoneNumber").appendChild('<div class="help-block">' + data.errors.phoneNumber + '</div>');
        }
        // handle errors for captcha ---------------
        if (data.errors.captcha) {
            swal({
                title: "Error!",
                text: data.errors.captcha,
                icon: "error",
            });
        }
        // handle errors for phpmailer ---------------
        if (data.message) {
            swal({
                title: "Error!",
                text: data.message,
                icon: "error",
                });
        }   
    else {
    //handle success messages
        swal({
            title: "Success!",
            text: data.message,
            icon: "success",
            });
    document.getElementById("form").reset();    
    }
}
});
})

I know that the field firstName does exist in the html but not sure why the javascript is not able to read the element.

ADDED HTML:

<html>
<head>
    <title>Melon Form</title>
    <link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css"> <!-- load bootstrap via CDN -->

    <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>

</head>
<body>
<div class="col-sm-6 col-sm-offset-3">

    <h1>Contact Form</h1>

    <!-- OUR FORM -->
    <form name="form" id="form" action="melonForm.php" method="POST">

        <!-- FIRST NAME -->
        <div id="firstName-group" class="form-group">
            <label for="firstName">First Name:</label>
            <input type="text" class="form-control" name="firstName" placeholder="Henry Pym">
            <!-- errors will go here -->
        </div>

        <!-- LAST NAME -->
        <div id="lastName-group" class="form-group">
            <label for="lastName">Last Name:</label>
            <input type="text" class="form-control" name="lastName" placeholder="Henry Pym">
            <!-- errors will go here -->
        </div>

        <!-- COMPANY NAME -->
        <div id="companyName-group" class="form-group">
            <label for="companyName">Company Name:</label>
            <input type="text" class="form-control" name="companyName" placeholder="Henry Pym">
            <!-- errors will go here -->
        </div>

        <!-- COMPANY ADDRESS -->
        <div id="companyAddress-group" class="form-group">
            <label for="companyAddress">Company Address:</label>
            <input type="text" class="form-control" name="companyAddress" placeholder="Henry Pym">
            <!-- errors will go here -->
        </div>

        <!-- CITY -->
        <div id="city-group" class="form-group">
            <label for="city">City:</label>
            <input type="text" class="form-control" name="city" id="city" placeholder="Henry Pym">
            <!-- errors will go here -->
        </div>

        <div id="state-group" class="form-group">
        <label for="state">State</label>
        <select id="state" name="state" class="form-control">
            <option value="" selected>Choose...</option>
            <option value="AL">Alabama</option>
            <option value="AK">Alaska</option>
            <option value="AZ">Arizona</option>
            <option value="AR">Arkansas</option>
            <option value="CA">California</option>
            <option value="CO">Colorado</option>
            <option value="CT">Connecticut</option>
            <option value="DE">Delaware</option>
            <option value="DC">District Of Columbia</option>
            <option value="FL">Florida</option>
            <option value="GA">Georgia</option>
            <option value="HI">Hawaii</option>
            <option value="ID">Idaho</option>
            <option value="IL">Illinois</option>
            <option value="IN">Indiana</option>
            <option value="IA">Iowa</option>
            <option value="KS">Kansas</option>
            <option value="KY">Kentucky</option>
            <option value="LA">Louisiana</option>
            <option value="ME">Maine</option>
            <option value="MD">Maryland</option>
            <option value="MA">Massachusetts</option>
            <option value="MI">Michigan</option>
            <option value="MN">Minnesota</option>
            <option value="MS">Mississippi</option>
            <option value="MO">Missouri</option>
            <option value="MT">Montana</option>
            <option value="NE">Nebraska</option>
            <option value="NV">Nevada</option>
            <option value="NH">New Hampshire</option>
            <option value="NJ">New Jersey</option>
            <option value="NM">New Mexico</option>
            <option value="NY">New York</option>
            <option value="NC">North Carolina</option>
            <option value="ND">North Dakota</option>
            <option value="OH">Ohio</option>
            <option value="OK">Oklahoma</option>
            <option value="OR">Oregon</option>
            <option value="PA">Pennsylvania</option>
            <option value="RI">Rhode Island</option>
            <option value="SC">South Carolina</option>
            <option value="SD">South Dakota</option>
            <option value="TN">Tennessee</option>
            <option value="TX">Texas</option>
            <option value="UT">Utah</option>
            <option value="VT">Vermont</option>
            <option value="VA">Virginia</option>
            <option value="WA">Washington</option>
            <option value="WV">West Virginia</option>
            <option value="WI">Wisconsin</option>
            <option value="WY">Wyoming</option>
        </select>
        </div>

        <!-- ZIPCODE -->
        <div id="zipcode-group" class="form-group">
            <label for="zipcode">Zipcode:</label>
            <input type="text" class="form-control" name="zipcode" id="zipcode" placeholder="12345">
            <!-- errors will go here -->
        </div>  

        <!-- EMAIL ADDRESS -->
        <div id="emailAddress-group" class="form-group">
            <label for="emailAddress">Email Address:</label>
            <input type="text" class="form-control" name="emailAddress" placeholder="rudd@avengers.com">
            <!-- errors will go here -->
        </div>

        <!-- PHONE NUMBER -->
        <div id="phoneNumber-group" class="form-group">
            <label for="phoneNumber">Phone Number:</label>
            <input type="text" class="form-control" name="phoneNumber" id="phoneNumber" placeholder="12345">
            <!-- errors will go here -->
        </div>  

        <!-- MESSAGE -->
        <div id="message-group" class="form-group">
            <label for="message">Message:</label>
            <input type="text" class="form-control" name="message" placeholder="Ant Man">
            <!-- errors will go here -->
        </div>

        <!-- GOOGLE RECAPTCHA -->
        <div class="form-group">
            <div class="g-recaptcha" data-sitekey="SECRET_KEY"></div>
        </div>

        <button type="submit" class="btn btn-success">Submit <span class="fa fa-arrow-right"></span></button>

    </form>

</div>
<script src="melonForm.js" defer></script> <!-- load our javascript file -->
</body>
<script src='https://www.google.com/recaptcha/api.js'></script>
</html>

Upvotes: 39

Views: 352924

Answers (4)

bprdev
bprdev

Reputation: 1048

This happened to me when I was using Preact, and inside of a component the selected variable was outside of a function that I was calling.

  const App = () => {
    const element = document.querySelector('[data-element]')

    const handleSomething = event => {
      element.classList.toggle('hidden')
    }

    return ()
  }

In that ^ code the function didn't know about the selected element, and threw the error. I solved it by creating a little helper function to toggle the class:

  const App = () => {
    const toggleElement = () => {
      const element = document.querySelector('[data-element]')
      element.classList.toggle('hidden')
    }

    const handleSomething = event => {
      // some code here....
      toggleElement()
    }

    return ()
  }

Upvotes: 0

Auguste
Auguste

Reputation: 2201

In my case I forgot to add a "." on my querySelector to select a class. If you are trying to select a class or an ID, check that you have the appropriate punctuation. For example:

const someclass = document.querySelector('.someclass');

To select an ID:

const someid = document.querySelector('#someid');

Also make sure that you spell the attribute that you trying to select correctly. Let's say for example you would like to select input but you misspell it on the selector below, it wont work.

Wrong one:

const input = document.querySelector('inputo'); 'inputo doesn't exist.

Correct one:

const input = document.querySelector('input');

Upvotes: 3

DEVANSHI SHAH
DEVANSHI SHAH

Reputation: 19

For me, the problem was that I had defined the element and had event listener to attached to it even before the DOM was created. We have to let the window be ready first.

So rather than doing this:

var myElement = document.querySelector("#my-element");
myElement.addEventListener("event", handler);

You can do this:

$(window).ready(()=>{
     var myElement = document.querySelector("#my-element");
     myElement.addEventListener("event", handler);
});

Don't forget to link jQuery, else you need to write

window.addEventListener("load", ()=>{
    var myElement = document.querySelector("#my-element");
    myElement.addEventListener("event", handler);
});

Upvotes: 0

Mark
Mark

Reputation: 5239

It means that document.getElementById("lastName") is returning undefined and you're trying to call classList on undefined itself.

In your HTML input has the attribute name which equals lastName but there is no actual id="lastname"

Either add the attribute id to your input or change getElementById to getElementsByName.

Note that getElementsByName doesn't return a single item.

Upvotes: 60

Related Questions