0

I am working on my node webserver and cannot get addEventListener to work with a button click for my website. I have simulated it on JS fiddle and it works perfectly fine!

https://jsfiddle.net/dxfqj4ys/2/

I am now trying to implement exact same thing for my actual website which i running on A Raspberry PI node.

My index.html


<script src="/socket.io/socket.io.js"></script>
<script>
    var socket = io.connect('/');
    socket.on('stats', function(data) {
        console.log('Connected clients:', data.numClients);
    });


document.addEventListener('click', function(){
  document.getElementById("demo").innerHTML = "Hello World!";
});


var button = document.getElementById("button1");
    button.addEventListener("click", function(event){
    document.getElementById('number1').textContent = 50;
});


</script>



<!DOCTYPE html>
<html>


<style>
table, th, td {
  border: 1px solid black;
  border-collapse: collapse;
}
th, td {
  padding: 5px;
  text-align: left;    
}
</style>
</head>


<div>
  <input id="button1" type="button" value="Add">
</div>

<br>

<div class="custom-select" style="width:200px;">
  <select>
    <option value="0">Select operation:</option>
    <option value="1">RUT240</option>
    <option value="2">FMB920</option>
  </select>
</div>

<br>



<table id="t1">
<caption>Operation table</caption>
    <thead>
        <tr>
            <th>Operation code</th>
            <th>To Do</th>
            <th>Done</th>
            <th>Left</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>RUT240</td>
            <td>1000</td>
            <td>50</td>
            <td>
            </td>
        </tr>
        <tr>
            <td>FMB920</td>
            <td>555</td>
            <td>50</td>
            <td id ="number1">  
            </td>
        </tr>
    </tbody>
</table>
<p id="demo"></p>
</html>

And my webserver.js

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var request = require('request');

//handles get request and serves index.html
app.get('/', function(req, res) {
    res.sendFile(__dirname + '/public/index.html');
});

server.listen(8080);




//THE FOLLOWING WILL COUNT THE NUMBERE OF CLIENTS
var numClients = 0;
io.on('connection', function(socket) 
{
    numClients++;
    io.emit('stats', { numClients: numClients });
    console.log('Connected clients:', numClients);
    socket.on('disconnect', function()
    {
        numClients--;
        io.emit('stats', { numClients: numClients });
        console.log('Connected clients:', numClients);
    });

});


As you can see from my .html, I have 2 event listeners, One is modifying element named "demo" and the other one is supposed to modify element with ID "number1".

The element with "demo" works fine, however, the "number1" does not work.

When I connect to the server from another computer as a client, open a developer menu and I can see the following error: enter image description here

Uncaught TypeError: Cannot read property 'addEventListener' of null

Lukas Petrikas
  • 65
  • 2
  • 11
  • Your js fiddle is updated, please check here https://jsfiddle.net/debnathrajdeep/8h0xt3ym/2/ – Vivek Bani Jun 03 '21 at 07:45
  • My apologies. I have added a wrong js fiddle. I have updated it in my initial question. I am just concerned why the same javascript not working on my actual webserver index.html while its on working on js fiddle. I have been trying to reorganize in many different ways but the same result ... – Lukas Petrikas Jun 03 '21 at 07:50
  • You can place the script inside `DOMContentLoaded` event as answered below. – Vivek Bani Jun 03 '21 at 08:07

2 Answers2

0

The error indicates that button is null, that's because your script executes before the DOM is ready and so before the actual button is present in it.

You just have to wait for the DOM to be ready before executing any script that requires to reference in-page elements:

window.addEventListener('DOMContentLoaded', () => {

  // Move your code in here

})

More information: Window: DOMContentLoaded event

Mereo4
  • 485
  • 5
  • 10
  • That works! I only add my javascript inside right? The rest stays the same – Lukas Petrikas Jun 03 '21 at 08:13
  • Yes, but it's mainly the code referring to in-page elements that needs to either be inside the `DOMContentLoaded` callback function, or as pointed out by @christos-panagiotakopoulos could also be inside a `` block after the element declarations. Apart from that, you should normally have `` and `` sections in your page, the scripts in `` will always execute before the DOM is populated. In ``, this is done sequentially top-to-bottom. – Mereo4 Jun 03 '21 at 11:39
0

Per this answer: Javascript element is null

Javascript is executed by the browser as it is encountered, which means that if your snippet of code exists in the page before the HTML element, then at that point in time, the HTML element does not yet exist.

You can re-arrange the code and put the script section after the HTML code like this:

<!DOCTYPE html>
<html>
<head>
<script src="/socket.io/socket.io.js"></script>

<style>
table, th, td {
  border: 1px solid black;
  border-collapse: collapse;
}
th, td {
  padding: 5px;
  text-align: left;    
}
</style>
</head>


<div>
  <input id="button1" type="button" value="Add">
</div>

<br>

<div class="custom-select" style="width:200px;">
  <select>
    <option value="0">Select operation:</option>
    <option value="1">RUT240</option>
    <option value="2">FMB920</option>
  </select>
</div>

<br>



<table id="t1">
<caption>Operation table</caption>
    <thead>
        <tr>
            <th>Operation code</th>
            <th>To Do</th>
            <th>Done</th>
            <th>Left</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>RUT240</td>
            <td>1000</td>
            <td>50</td>
            <td>
            </td>
        </tr>
        <tr>
            <td>FMB920</td>
            <td>555</td>
            <td>50</td>
            <td id ="number1">  
            </td>
        </tr>
    </tbody>
</table>
<p id="demo"></p>
<script>
    var socket = io.connect('/');
    socket.on('stats', function(data) {
        console.log('Connected clients:', data.numClients);
    });


document.addEventListener('click', function(){
  document.getElementById("demo").innerHTML = "Hello World!";
});


var button = document.getElementById("button1");
    button.addEventListener("click", function(event){
    document.getElementById('number1').textContent = 50;
});


</script>
</html>