Last updated: Mar 2, 2024
Reading time·3 min
The "setAttribute is not a function" error occurs for multiple reasons:
setAttribute()
method on a value that is not a DOM element.setAttribute
method on a jQuery object (should use attr()
instead).If you use jQuery, use the attr()
method instead of setAttribute
.
const box = $('#box'); console.log(box); // ✅ works box.attr('id', 'first');
Here is an example of how the error occurs in JavaScript.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <div class="box">Box 1</div> <div class="box">Box 2</div> <div class="box">Box 3</div> <!-- ✅ Your JS script here ✅ --> <script type="module" src="index.js"></script> </body> </html>
script
has to be below the code that declares the DOM elements.Notice that the JS script tag is placed at the bottom of the body tag.
Had we placed the JS script tag above the code that declares the DOM elements,
they wouldn't be accessible in the index.js
file.
Here is the code in index.js
.
const boxes = document.querySelectorAll('.box'); console.log(boxes); // 👉️ [div.box, div.box, div.box] // ⛔️ Uncaught TypeError: boxes.setAttribute is not a function boxes.setAttribute('id', 'first');
We called the Element.setAttribute()
method on a NodeList
and not a DOM element, which caused the error.
Make sure to only call the setAttribute
method on valid DOM elements and place
the JS script tag at the bottom of the body, after the DOM elements have been
declared.
const boxes = document.querySelectorAll('.box'); console.log(boxes); // 👉️ [div.box, div.box, div.box] // ✅ Works boxes[0].setAttribute('id', 'first');
By accessing the element at index 0
of the NodeList
, we got back a DOM
element, on which we can safely call the setAttribute
method.
If you need to use the setAttribute()
method on all elements in the
collection, use the forEach()
method.
const boxes = Array.from(document.querySelectorAll('.box')); console.log(boxes); // 👉️ [div.box, div.box, div.box] boxes.forEach(box => { box.setAttribute('title', 'example'); });
We used the Array.from()
method to convert the collection of elements to an
array and use the Array.forEach()
method to iterate over the array.
On each iteration, we call the setAttribute()
method on the element.
setAttribute
methodIf the element you are calling the method on sometimes doesn't exist, you can
conditionally check if the element is there before calling the setAttribute
method.
For example, a basic DOM element has a type of object, so we can check if the
value is an object and contains the setAttribute
property before calling the
method.
const box = null; if ( typeof box === 'object' && box !== null && 'setAttribute' in box ) { box.setAttribute('id', 'example'); }
Our if
condition uses the logical AND (&&) operator, so for the if
block to
run, all the conditions have to be met.
We first
check if the box
variable stores a value with a type of object,
because DOM elements have a type of object.
Then we
check if the variable is not equal to null.
Unfortunately, if you check the type of null with console.log(typeof null)
,
you will get an "object"
value back, so we have to make sure the value is not
null
.
setAttribute
property.Then we know we can safely call the setAttribute
method on the object.
This approach is called duck-typing.
When using duck-typing, we simply check if the object implements specific properties or methods and if it does, we assume it's an object of the correct type.
To solve the "setAttribute is not a function" error, make sure to only call
the setAttribute
method on valid DOM elements and place the JS script tag at
the bottom of the body, after the DOM elements have been declared.