1

I have read LWC document and known to use "connectedCallback" to perform Javascript's onload function.

Ref: Javscript onload in LWC

However, it does not perform as expected. I can add classList successfully and retrieve it successfully, too. But, I can not get the element at all! It makes confuses and what are the reasons for the result?

LWC.html

<template>
  <div>block 1</div>
  <div>block 2</div>
  <div>block 3</div>
</template>

LWC.js

connectedCallback() {
  this.classList.add('new-class'); // Success!
  alert('this.classList: ' + this.classList); // Success: this.classList: new-class
  alert(this.querySelectorAll('.new-class').length); // Expect: 1, Actual: 0!! Why?
  alert('this.nodeName: ' + this.nodeName); // Expected: (nodeName of the host element), Actual: this.nodeName: undefined
  alert(this.querySelectorAll('div')); // Expected: 3, Actual: 0
  alert(this.template.querySelectorAll('div')); // Expected: 3, Actual: 0
}

The first and second connectedCallback() (a.k.a onload for LWC) statement works successfully.

But...

  1. the 3rd statement can not retrieve the DOM by querySelectorAll(). Why?
  2. the 4th statement's result expects to display the nodeName of the host element, but it does not. The actual result is "undefined".
  3. the 5th or 6th statement's result expects to be "3", but actually it is "0"?
3

In LWC "this" is not a DOM element. It is the LWC's "controller" object (if you consider it like an Aura component). Doing "this.classList" simply adds a "classList" property to the LWC "controller" instance.

What you actually need to look at is the LWC's "template". Take a look at the documentation on this subject, which shows access to the template using

this.template

and the application of DOM element retrieval like:

this.template.querySelectorAll('div');

Note, in addition, that you should do this sort of thing in the renderedCallback, not the connectedCallback, because the DOM will be created after the connectedCallback and before the renderedCallback. See the LWC lifecycle documentation for more detail.

3
  • There is no way to access the root (host) element, right? For an example: to get the width of the root element. – Cray Kao Dec 18 '19 at 18:21
  • Well, it depends on the structure. A template contains a document fragment, so the component may effectively have multiple "root nodes". If you have the template contain just one child (e.g. div) that contains everything else, you can certainly get that child. – Phil W Dec 18 '19 at 18:30
  • Thank you. Got it. ^_^ – Cray Kao Dec 18 '19 at 18:40
0

querySelectorAll() only matches against nodes inside of the node that you call it from.

Since you're adding the new-class class to the root of the component (this) but not on anything inside of it, calling this.querySelectorAll('.new-class') doesn't match anything because only the component has the new-class class - no element inside of it does.

Even outside of an LWC you'd see this behavior.

1
  • 1
    Thank you for the answer. You are right. The result is so because querySelectorAll() can not access the host or root element of the LWC. But, why the 3rd, 4th, 5th, and 6th statements does not work? I just updated the question. – Cray Kao Dec 18 '19 at 15:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.