Reputation: 509
I have a function that loops over each element of the array and outputs the html content to the page while modifying some properties with elements from the array. I'm using forEach
to loop over elements of the array and innerHTML
to print content to the page.
I keep getting the following error: netdata.html:41 Uncaught TypeError: Cannot set property 'innerHTML' of null
. I'm not sure what's causing it as I do have an element with the proper id, <div id="info"></div>
const clusterIPs = [
{ name: "eco-cluster-1", ip: "192.168.50.101" },
{ name: "eco-cluster-2", ip: "192.168.50.102" },
{ name: "eco-cluster-3", ip: "192.168.50.103" },
{ name: "eco-cluster-4", ip: "192.168.50.104" },
{ name: "eco-cluster-6", ip: "192.168.50.105" },
{ name: "eco-cluster-7", ip: "192.168.50.106" },
{ name: "eco-cluster-8", ip: "192.168.50.107" },
{ name: "eco-cluster-9", ip: "192.168.50.108" },
{ name: "eco-cluster-10", ip: "192.168.50.110" },
{ name: "eco-cluster-11", ip: "192.168.50.111" },
{ name: "eco-cluster-12", ip: "192.168.50.112" },
{ name: "eco-cluster-13", ip: "192.168.50.113" }
];
clusterIPs.forEach(pc => {
console.log(pc);
// $("body").html
document.getElementById("info").innerHTML = `
<div class="container-fluid">
<div><h1>${pc.name}</h1></div>
<div class="row">
<div class="col-md">
<div
data-title="CPU"
data-netdata="system.cpu"
data-chart-library="dygraph"
data-after="-600"
data-host="http://${pc.ip}:19999/"
></div>
</div>
<div class="col-md">
<div
data-title="RAM"
data-netdata="system.ram"
data-chart-library="dygraph"
data-after="-600"
data-host="http://${pc.ip}:19999/"
></div>
</div>
</div>
<div class="row">
<div class="col-md">
<div
data-title="Disk I/O"
data-netdata="system.io"
data-chart-library="dygraph"
data-after="-600"
data-host="http://${pc.ip}:19999/"
></div>
</div>
<div class="col-md">
<div
data-title="Network Bandwidth"
data-netdata="system.net"
data-chart-library="dygraph"
data-after="-600"
data-host="http://${pc.ip}:19999/"
></div>
</div>
</div>
</div>
`;
});
// console.log(clusterIPs)
Upvotes: 0
Views: 70
Reputation: 545
The div#info
element is not available when the script runs. There are several ways to solve this:
DOMContentLoaded
event listener to the document
object, then in the callback run the existing script. <script>
tag containing the existing script AFTER the div#info
element. Component Representing HTML Element
class Component {
constructor() {}
get element() {
if(this._element) return this._element
this._element = document.createElement('div')
this._element.setAttribute('id', 'info')
return this._element
}
get data() { return [
{ name: "eco-cluster-1", ip: "192.168.50.101" },
{ name: "eco-cluster-2", ip: "192.168.50.102" },
{ name: "eco-cluster-3", ip: "192.168.50.103" },
{ name: "eco-cluster-4", ip: "192.168.50.104" },
{ name: "eco-cluster-6", ip: "192.168.50.105" },
{ name: "eco-cluster-7", ip: "192.168.50.106" },
{ name: "eco-cluster-8", ip: "192.168.50.107" },
{ name: "eco-cluster-9", ip: "192.168.50.108" },
{ name: "eco-cluster-10", ip: "192.168.50.110" },
{ name: "eco-cluster-11", ip: "192.168.50.111" },
{ name: "eco-cluster-12", ip: "192.168.50.112" },
{ name: "eco-cluster-13", ip: "192.168.50.113" }
] }
get template() { return (pc) => `
<div class="container-fluid">
<div><h1>${pc.name}</h1></div>
<div class="row">
<div class="col-md">
<div
data-title="CPU"
data-netdata="system.cpu"
data-chart-library="dygraph"
data-after="-600"
data-host="http://${pc.ip}:19999/"
></div>
</div>
<div class="col-md">
<div
data-title="RAM"
data-netdata="system.ram"
data-chart-library="dygraph"
data-after="-600"
data-host="http://${pc.ip}:19999/"
></div>
</div>
</div>
<div class="row">
<div class="col-md">
<div
data-title="Disk I/O"
data-netdata="system.io"
data-chart-library="dygraph"
data-after="-600"
data-host="http://${pc.ip}:19999/"
></div>
</div>
<div class="col-md">
<div
data-title="Network Bandwidth"
data-netdata="system.net"
data-chart-library="dygraph"
data-after="-600"
data-host="http://${pc.ip}:19999/"
></div>
</div>
</div>
</div>
` }
insertElement() {
document.querySelector('body')
.insertAdjacentElement('afterbegin', this.element)
return this
}
clearElement() {
this.element.innerHTML = ''
return this
}
render() {
if(!this.element.parentElement) {
this.insertElement()
} else {
this.clearElement()
}
this.data.forEach((dataItem) => {
let template = document.createRange().createContextualFragment(
this.template(dataItem)
)
this.element.appendChild(template)
})
return this
}
}
Instantiate Component
document.addEventListener('DOMContentLoaded', (event) => {
let component = new Component()
component.render()
})
Upvotes: 0
Reputation: 178350
You are
To use innerHTML you can do
window.addEventListener("load",function() {
const container = document.getElementById("info");
clusterIPs.forEach(pc => container.innerHTML += `....`);
})
Or use jQuery to append since you already load it
$(function() { // on page load
const $container = $("#info");
$.each(clusterIPs,(i, pc) => {
$container.append(`....`);
});
});
const clusterIPs = [
{ name: "eco-cluster-1", ip: "192.168.50.101" },
{ name: "eco-cluster-2", ip: "192.168.50.102" },
{ name: "eco-cluster-3", ip: "192.168.50.103" },
{ name: "eco-cluster-4", ip: "192.168.50.104" },
{ name: "eco-cluster-6", ip: "192.168.50.105" },
{ name: "eco-cluster-7", ip: "192.168.50.106" },
{ name: "eco-cluster-8", ip: "192.168.50.107" },
{ name: "eco-cluster-9", ip: "192.168.50.108" },
{ name: "eco-cluster-10", ip: "192.168.50.110" },
{ name: "eco-cluster-11", ip: "192.168.50.111" },
{ name: "eco-cluster-12", ip: "192.168.50.112" },
{ name: "eco-cluster-13", ip: "192.168.50.113" }
];
$(function() { // on page load
const $container = $("#info");
$.each(clusterIPs,(i, pc) => {
$container.append(`
<div class="container-fluid">
<div><h1>${pc.name}</h1></div>
<div class="row">
<div class="col-md">
<div
data-title="CPU"
data-netdata="system.cpu"
data-chart-library="dygraph"
data-after="-600"
data-host="http://${pc.ip}:19999/"
></div>
</div>
<div class="col-md">
<div
data-title="RAM"
data-netdata="system.ram"
data-chart-library="dygraph"
data-after="-600"
data-host="http://${pc.ip}:19999/"
></div>
</div>
</div>
<div class="row">
<div class="col-md">
<div
data-title="Disk I/O"
data-netdata="system.io"
data-chart-library="dygraph"
data-after="-600"
data-host="http://${pc.ip}:19999/"
></div>
</div>
<div class="col-md">
<div
data-title="Network Bandwidth"
data-netdata="system.net"
data-chart-library="dygraph"
data-after="-600"
data-host="http://${pc.ip}:19999/"
></div>
</div>
</div>
</div>`)
});
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous" />
<div id="info"></div>
<script type="text/javascript" src="http://localhost:19999/dashboard.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha256-pasqAKBDmFT4eHoN2ndd6lN370kFiGUFyTiUHWhU7k8=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
Upvotes: 1