-1

I have 2 elements with 'copyright' class and wanted to change their textContent but it shows me an error: Uncaught TypeError: can't assign to property "textContent" on 2: not an object

const copyright = document.querySelectorAll('.copyright')
for (let i in copyright) {
    copyright[i].textContent = new Date().getFullYear()
}

I tried to use innerHTML but it didn't change much

  • 1
    It's working fine in my side – flyingfox Nov 17 '22 at 02:00
  • 1
    In here `for (let i in copyright)` the variable `i` is not an index, but the element itself. so inside the loop `i.textContent = 'foo'` should suffice – Jhilton Nov 17 '22 at 02:03
  • 2
    @Jhilton It's not,you can test the code by youself and it will works fine – flyingfox Nov 17 '22 at 02:03
  • 3
    [Don't use `for…in` enumerations on array-like objects!](https://stackoverflow.com/q/500504/1048572) – Bergi Nov 17 '22 at 02:04
  • 1
    @Jhilton No. It's not `for … of` – Bergi Nov 17 '22 at 02:04
  • 2
    Can you make a [mcve] please, ideally [as a StackSnippet](https://meta.stackoverflow.com/q/358992/1048572), that demonstrates the problem and throws that error? – Bergi Nov 17 '22 at 02:06
  • 1
    SUGGESTION: Add `console.log('i:' + i + ', copyright[i]: ' + copyright[i]);` to your loop -*BEFORE* your assignment - and see what happens under Chrome Developer Tools (or equivalent). I suspect one of the elements in your HTML isn't what you expect it to be... – paulsm4 Nov 17 '22 at 02:14
  • @paulsm4 Better: `console.log({ i, "copyright[i]": copyright[i] });`. Avoid coercing everything to strings. Alternatively, use a debugger. – Sebastian Simon Nov 17 '22 at 02:17
  • 1
    @lucumt try in "strict mode" you'll get the same error as OP. – Kaiido Nov 17 '22 at 02:52
  • Now the question is "Why did they make these properties enumerable?"... – Kaiido Nov 17 '22 at 03:07
  • 1
    To myself: There was https://github.com/whatwg/webidl/issues/738 – Kaiido Nov 17 '22 at 03:26

1 Answers1

1

Use forEach, for ... of, or an usual for loop instead. With these you can access every element in the NodeList. Because NodeList is not a normal Array, using for...in on it will give you other properties of the NodeList object, like "item", "keys", and the problematic one in your case, .length. Indeed, in "strict mode", you can't set properties on number primitives.

Using forEach that would give:

const copyright = document.querySelectorAll('.copyright');
copyright.forEach(elem => {
    elem.textContent = new Date().getFullYear();
})

Using for...of:

const copyright = document.querySelectorAll('.copyright');
for(const elem of copyright) {
    elem.textContent = new Date().getFullYear();
}

And using the usual for loop:

const copyright = document.querySelectorAll('.copyright');
for(let i = 0; i < copyright.length; i++) {
    copyright[i].textContent = new Date().getFullYear();
}
Kaiido
  • 123,334
  • 13
  • 219
  • 285
Layhout
  • 1,445
  • 1
  • 3
  • 16