Object is defined but JavaScript says it is not

This is very strange and frustrating. The object is defined but JavaScript insists it is not. The following is a simplified version of the code.

let containers = document.body.getElementsByClassName("container");
var container;
for (x=0; x<containers.length; ++x) {
	if (containers[x].parentElement.nodeName === "BODY") {
		container = containers[x];
		console.log("container is now a "+container.name);
		}
    }
if (container.name == 'undefined') {
	console.log("No container");
	return;
	}
if (container == null) {
console.log("Container is null");
return;
}

What I am trying to do is to get the div with class=container that is at the top of the hierarchy; in other words, the parent is the body. In the loop the div is found. containers[x] works. Yet the message says that container (and containers[x] if I try to show it) is a undefined. Yet after the loop container.name == 'undefined' is false. There is obviously a peculiarity of JavaScript that I just do not see.

1 Like

Kinda… container.name is indeed undefined which is a special value in JS; however by concatenating it to a string in this line

console.log("container is now a "+container.name);

you’re implicitly coercing the value of undefined to the string 'undefined', which again is not actually undefined. So the expression container.name == 'undefined' will evaluate to false, while

if (container.name == undefined) {
  // ...
}

would pass your test.

1 Like

Use of name in that manner is something I found somewhere to test if an object has a value. I want to ensure that container got a value in the loop. I could do many other things but is it possible to check if it got a value in the loop? Is it possible to check if it is undefined? Ideally I should ensure that it is a HTMLDivElement but that would fail if the object is undefined. I could wrap that in a try and catch. So now I have the following and I think that will work.

try {
	if (!(container instanceof HTMLDivElement)) {
		console.log("container is not a HTMLDivElement");
		return;
	}
}
catch (err) {
	console.log("container error: "+err.message);
	return;
}

Because there are several different understandings that can be incorrect about your situation, can you please show us some examples of HTML that match your conditions and other HTML that fails to match your conditions?

That way, we can come up with a suitable solution that aims to do the job well.

1 Like

Thank you. I think I can proceed on my own. Part of the problem might have been use of let; I tried many things and I used let in a way that was a problem.

I am still having problems checking for undefined but checking for null seems to work.

I am trying to modify an extension I wrote that manipulates HTML in a website page. They apparently modified the HTML more than I realized but I think I can proceed now.

FWIW, you might just query for div elements only from the first:

const containers = document.querySelectorAll('div.container')

Or even div elements that are direct children of the body:

const containers = document.querySelectorAll('body > div.container')

And based on the code’s execution paths based on what you’ve shown, you can simply do

const container = document.querySelector("body > div.container:last-of-type");

and save yourself the loop entirely.