I'm getting the following error
Uncaught TypeError: Cannot read property 'appendChild' of null
myRequest.onreadystatechange @ script.js:20
with my following code
// index.html
<html>
<head>
<title>Simple Page</title>
</head>
<body>
<div id="mainContent">
<h1>This is an AJAX Example</h1>
</div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
And here is my JavaScript file
// script.js
// 1. Create the request
var myRequest;
// feature check!
if(window.XMLHttpRequest) { // Firefox, Safari
myRequest = new XMLHttpRequest();
} else if (window.ActiveXObject){ // IE
myRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
// 2. Create an event handler for our request to call back
myRequest.onreadystatechange = function() {
console.log("We were called!");
console.log(myRequest.readyState);
if(myRequest.readyState === 4){
var p = document.createElement("p");
var t = document.createTextNode(myRequest.responseText);
p.appendChild(t);
document.getElementById("mainContent").appendChild(p);
}
};
// 3. open and send it
myRequest.open("GET","simple.txt", true);
// any parameters?
myRequest.send(null);
And here is the contents of simple.txt
This is the contents of a simple text file.
I put the script tag at the bottom of the html as suggested by @Tejs here but I'm still getting this error.
This question is related to
javascript
ajax
those getting querySelector or getElementById that returns the following error:
Uncaught TypeError: Cannot read property 'appendChild' of null
or any other property, even if you have a class name or id in the HTML
don't use (defer as it is too much browser dependent.)
<script src="script.js" defer></script> //don't use this
instead, put all your code in 'script.js' inside
$(document).ready(function(){
//your script here.
}
If this is happening to you in an AJAX post, you'll want to compare the values that you're sending and the values that the Controller is expecting.
In my case, I had changed a parameter in a serializable class from State to StateID, and then in an AJAX call didn't change the receiving field out 'data'
success: function (data) { MakeAddressForm.formData.StateID = data.State;
Note that the class was changed - it doesn't matter what I call it in the formData.
This created a null reference in the formData which I was trying to post back to the Controller once I'd done the update. Obviously, if someone changed the state (which was the purpose of the form) then they didn't get the error, so it made for a hard one to find.
This also through a 500 error. I'm posting this here in hopes it saves someone else the time I've wasted
Use querySelector insted of getElementById();
var c = document.querySelector('#mainContent');
c.appendChild(document.createElement('div'));
add your script tag on the bottom of the body tag. so that script loads after html content then you won't get such error and add=
Had the same problem when Load external without cache using Javascript
Load external <script> without cache using Javascript
Had a good solution for cache problem here:
But this happend: Uncaught TypeError: Cannot read property 'appendChild' of null.
Here is good explanation: https://stackoverflow.com/a/58824439/14491024
As it said your script tag is in the head, the JavaScript is loaded before your HTML.
In Visual Studio by C# this problem is solved like this by adding Guid:
Here is how it looks in the View page source:
Instead of using your script tag defining the source of your .js file in <head>
, place it at the bottom of your HTML code.
Nice answers here. I encountered the same problem, but I tried <script src="script.js" defer></script>
but I didn't work quite well. I had all the code and links set up fine. The problem is I had put the js file link in the head of the page, so it was loaded before the DOM was loaded. There are 2 solutions to this.
window.onload = () => { //write your code here }
<script src="script.js"></script>
to the bottom of the html file so that it loads last.put your javascript at the bottom of the page (ie after the element getting defined..)
For people who have the same issue of querySelector
or getElementById
that returns the following error:
Uncaught TypeError: Cannot read property 'appendChild' of null
but you have a class name or id in the HTML...
If your script tag is in the head, the JavaScript is loaded before your HTML. You will need to add defer
to your script like so:
<script src="script.js" defer></script>
You can load your External JS files in Angular and you can load them directly instead of defining in index.html file.
component.ts:
ngOnInit() {
this.loadScripts();
}
loadScripts() {
const dynamicScripts = [
//scripts to be loaded
"assets/lib/js/hand-1.3.8.js",
"assets/lib/js/modernizr.jr.js",
"assets/lib/js/jquery-2.2.3.js",
"assets/lib/js/jquery-migrate-1.4.1.js",
"assets/js/jr.utils.js"
];
for (let i = 0; i < dynamicScripts.length; i++) {
const node = document.createElement('script');
node.src = dynamicScripts[i];
node.type = 'text/javascript';
node.async = false;
document.getElementById('scripts').appendChild(node);
}
}
component.html:
<div id="scripts">
</div>
You can also load styles similarly.
component.ts:
ngOnInit() {
this.loadStyles();
}
loadStyles() {
const dynamicStyles = [
//styles to be loaded
"assets/lib/css/ui.css",
"assets/lib/css/material-theme.css",
"assets/lib/css/custom-style.css"
];
for (let i = 0; i < dynamicStyles.length; i++) {
const node = document.createElement('link');
node.href = dynamicStyles[i];
node.rel = 'stylesheet';
document.getElementById('styles').appendChild(node);
}
}
component.html:
<div id="styles">
</div>
Source: Stackoverflow.com