Hi, would really appreciate some help. I am currently undertaking an online Javascript course, and in a previous session we were creating a simple photo gallery, but my computer crashed so I missed the explanation. Anyway, our tutor provided his code after and I since attempted it on my own. When this wasn’t working, I referred back to the code he provided and copied it exactly. However, it doesn’t work and I get this error in the console every time: “Uncaught TypeError: Cannot read property ‘insertBefore’ of null”.
I am very much at the beginning of my JS journey, and my understanding is limited. I’m also working through the FreeCodeCamp JS course at the same time. I just don’t understand why I’m getting this error, especially if I’m using the same code as my tutor, and as far as I understand his is working. I’d really appreciate some help on this as I want to resolve this weekend and I have already spent hours on Google trying. I feel stupid!
I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.
You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.
Thanks for your feedback. My tutor said that you don’t always need to declare global variables like this, and his code has them declared in the same way as the code I posted. But I was under the impression that you needed ‘let’ or const’ in front, as you mentioned…
Anyhow, I tried declaring the variables with the let keyword, and then I get an error saying “Uncaught SyntaxError: let is disallowed as a lexically bound name” instead. Will keep trying to figure this out.
Technically, you don’t need to declare your variables with a keyword, that’s true. But it’s horrible practice. If someone teaches you JavaScript like this, I’d consider finding another tutor…
That’s probably because you’ve declared them like this:
let insertPoint = document.getElementById('thumbPoint'),
let thumbnail,
let a_tag;
That won’t work, you’ll need to replace those commas at the end of each line with semicolons.
Otherwise, only use let for the first declaration:
let insertPoint = document.getElementById('thumbPoint'),
thumbnail,
a_tag;
Hi, I had changed all of the commas to semicolons before reloading and got that error message. After reading your message, I Googled something in relation and read that I needed to, before changing anything. Strange huh.
Thanks for the advice on what my tutor had taught… Slightly concerning but good to know!
No, that error doesn’t appear, so thank you for resolving that, but the code still doesn’t work and the error message “Uncaught SyntaxError: let is disallowed as a lexically bound name” comes up instead.
Do I need to declare the let keyword in front of all uses of a_tag and thumbnail variables within the function too? Updated code below. Thanks very much for all your help!
//2 global variables
let insertPoint = document.getElementById('thumbPoint');
let thumbnail;
let a_tag;
//3 loop
for (let i = 0; i < photos.length; i++){
a_tag = document.createElement('a');
a_tag.href = photos[i].href;
thumbnail = document.createElement('img');
thumbnail.src = photos[i].src;
thumbnail.width = '100';
thumbnail.height = '100';
a_tag.appendChild(thumbnail);
document.body.insertBefore(a_tag, insertPoint);
a_tag.addEventListener('click', showImage);
}
This error is still there because there’s still a comma after the declaration of the photos variable, that should be a semicolon too.
After you’ve declared a variable with let, JavaScript knows it’s a variable. In fact, you’d get an error if you want to redeclare it with let again.
In your example, the global scope is aware of the variables insertPoint, thumbnail and a_tag, and the function can look outside itself and knows what those variables are, so no need to re-declare them inside the function.
You’re trying to use the .insertBefore method on document.body, which should definitely not be null. Unless your script runs before the DOM is loaded, so I’d suggest the following, wrap your whole code inside an event listener like this:
document.addEventListener('DOMContentLoaded', () => {
// your whole code goes here within the curly braces
}