I have an event listener for click events on the document and I am using composedPath to determine if anything in the path includes a certain attribute.
If something in the path does include an attribute I listen for then all is well and everything works.
However, if something in the path does not include an attribute I listen for then it throws an exception:
"Uncaught TypeError: el.hasAttribute is not a function"
Here is a fiddle showing this:
document.addEventListener('click', (event) => {
const includesAttribute = event.composedPath().some((el) => el.hasAttribute('my-attribute'));
console.log(`has attribute: ${includesAttribute}`);
});
<button my-attribute>click me, I log true and work fine</button>
<br/>
<button other-attribute>click me, I throw an exception because I don't have the attribute</button>
Why do I get an exception only when the attribute does not exist? Shouldn't the hasAttribute method always be available?
Because document does not have the method getAttribute. Your call to some is getting all the way to document when it doesn't find anything; see the logging of nodeName here:
document.addEventListener('click', (event) => {
const includesAttribute = event.composedPath().some((el) => {
console.log(el.nodeName);
return el.hasAttribute('my-attribute');
});
console.log(`has attribute: ${includesAttribute}`);
});
<button my-attribute>click me, I log true and work fine</button>
<br/>
<button other-attribute>click me, I throw an exception but now you can see why</button>
Just add a guard:
document.addEventListener('click', (event) => {
const includesAttribute = event.composedPath().some((el) => el.hasAttribute && el.hasAttribute('my-attribute'));
console.log(`has attribute: ${includesAttribute}`);
});
document.addEventListener('click', (event) => {
const includesAttribute = event.composedPath().some((el) => el.hasAttribute && el.hasAttribute('my-attribute'));
console.log(`has attribute: ${includesAttribute}`);
});
<button my-attribute>click me, I log true and work fine</button>
<br/>
<button other-attribute>click me, I do not throw an exception anymore</button>