1

I have a component and am trying to retrieve an element from the template using querySelector, as follows:

const elt = this.template.querySelector('.thunder-ng');

But instead of returning the element, or null, it returns an odd object which only has an toString method defined, which yields this:

"SecureObject: [object HTMLDivElement]{ key: {"namespace":"c"} }"

I traced way down inside querySelector and finally I could see where it was generating that weird object, but it was beyond me to figure out why. Here's the code where it ends up:

function SecureObject(thing, key) {
    let o = getFromCache(thing, key);
    if (o) {
      return o;
    }

    o = create(null, {
      toString: {
        value: function() {
          return `SecureObject: ${thing}{ key: ${JSON.stringify(key)} }`;
        },
      },
    });

    setRef(o, thing, key, true);
    addToCache(thing, o, key);
    registerProxy(o);

    return seal(o);
  }

One cannot do anything with this malformed stub object. It is not an actual element. The fact that it contains just an toString method is not an artifact of DevTools; that is really just what the object is. As such, of course any and all attempts to treat it like a DOM element, such as inserting DOM content using appendChild or innerHTML, fail.

const elt = this.template.querySelector('thunder-ng');
elt.appendChild(newChild); /// `undefined is not a function

The template is quite innocuous:

<template>
  <slot></slot>
  <div lwc:dom="manual" class="thunder-ng" role="application"></div>
</template>

Neither the lwc:dom nor the slots seem to make any difference. The problem persists.

The annoying thing is that this was working at some point in the past, and then suddenly stopped working, but of course I can't identify what I did to make it stop working.

I'm guessing this is some kind of namespace mismatch, but that's odd, because all my components are very much in the same namespace as far as I know.

11
  • 2
    What exactly is the problem? Are you trying to modify the element? Did you try to set innerHTML but failed? What is the failure message? Commented Aug 4, 2020 at 19:50
  • Yes, as the lwc:dom might indicate, I'm trying to appendChild into that element. But I can't do that or innerHTML or anything else because it's not even an element. It's just an object with a single toString method.
    – kamezaburo
    Commented Aug 4, 2020 at 20:01
  • @kamezaburo I guess you got the above object structure inside console.log, the dom element is secured when you log it on the console, so there should not be an issue with DOM manipulation. Commented Aug 5, 2020 at 7:14
  • 1
    @rahulgawale Actually, there is a problem, since what comes back from querySelector is not a DOM element in any sense of the word. It's just an object with a single toString method. elt.appendChild returns undefined, and elt.appencChild(child) of course tells me that appendChild is not a function.
    – kamezaburo
    Commented Aug 5, 2020 at 16:15
  • 2
    I figured it out. It was a bit different from your use case, but basically, the code was being run when I dragged a sub-component (using js's draggable api). The code was running in the sub-component's context, which didn't have access to the element referenced by querySelector.
    – willard
    Commented Nov 19, 2020 at 15:10

0

You must log in to answer this question.

Browse other questions tagged .