Skip to content
Advertisement

TypeScript cant read property addEventListener

I’m learning TypeScript and I’m following a youtube tutorial that I did step by step. But for some reason I’m still receving a error.

Uncaught TypeError: Cannot read property ‘addEventListener’ of null

I rewrote the code twice and I’m still receiving the same error. Could u guys pls help me understand what’s wrong and why.

I’m still a rookie, but it’s driving me crazy.

Tks in advanced.

//Interface
interface PersonObjInterface{
    name: string,
    age: number
}

//Interface for Obj
let objPerson: PersonObjInterface = {
    name: "John Doe",
    age: 40
}

//Interface for Class
class ClassPerson implements PersonObjInterface{
    constructor(public name: string, public age: number){}
    greet(){
        return `Hi, my name is ${this.name} and I am ${this.age} yo.`
    }
}

//let John = new ClassPerson("John", 40)
//console.log(John.greet());

//DOM
const inputName = document.querySelector('#name') as HTMLInputElement
const inputAge = document.querySelector('#age') as HTMLInputElement
const inputForm = document.querySelector('form')!
const greeting = document.querySelector('.greeting') as HTMLDivElement

inputForm.addEventListener('submit', (e) => {
    e.preventDefault()
    const person = new ClassPerson(inputName.value, inputAge.valueAsNumber)
    greeting.innerText = person.greet()
    inputForm.reset()
})

The html

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="app.js"></script>
    <title>TypeScript Crash Course</title>
</head>
<body>
    <form>
        <input type="text" name="name" id="name" />
        <input type="number" name="age" id="age" />
        <input type="submit" value="Say hi" />
    </form>
    <div class="greeting"></div>
</body>

Advertisement

Answer

You are loading your app.js in the header of your html document. At this time, there is no <body> or <form>, because the DOM is not fully loaded yet. So all your document.querySelector() calls will return null.

The easiest solution is to load your script in the end of the HTML document, so all the DOM elements already exist.

<html>
<head>
 ...
</head>
<body>
  ...
  <script src="app.js"></script>  <!-- move script loading from head to here -->
</body>
</html>

As an alternative you can also use the defer attribute when loading your script, which will execute the script only after the page has loaded, reagardless where the script tag is placed. But this only works for external scripts loaded via src=... attribute.

<html>
<head>
  <script src="app.js" defer></script> 
 ...
</head>
<body>
  ...
</body>
</html>
Advertisement