0

I'm working in a Lightning Aura component, and when I run it in the browser it's saying that my element is undefined.

HTML

<div id="myElement">
    ...
</div>

Controller.js

doInit: function(component, event, helper) {
    helper.myFunction(component, event, helper);
}

Helper.js

myFunction: function(component, event, helper) {
    const myElement = document.getElementById("myElement");
    $A.util.addClass(myElement , "hello-world");
},

I've tried a variation by setting aura:id on the HTML element...

HTML

<div aura:id="myElement">
    ...
</div>

Helper.js

myFunction: function(component, event, helper) {
    const myElement = component.find("myElement").getElement();
    $A.util.addClass(myElement , "hello-world");
},

But the results are the same: myFunction still comes across as undefined.

2
  • The find/aura:id method should work. The one you've posted here will not work.
    – sfdcfox
    Commented Jun 24, 2020 at 19:34
  • I updated the above question to show the aura:id/find version I'm using which also says my element is undefined.
    – Matt Smith
    Commented Jun 24, 2020 at 19:51

2 Answers 2

0

Getting/using native element Id's is typically a bad idea with dynamic content in general. You are on the right track with setting the aura:id attribute, and using component.find(), but i think you are simply missing the following getElement() to get what you are looking for. Try setting your aura:id property again, and grab it in your controller using:

myElement = component.find("myElement").getElement();
1
  • Thanks, I tried that and I'm getting the same error, just a variation: TypeError: Cannot read property 'getElement' of undefined.
    – Matt Smith
    Commented Jun 24, 2020 at 19:43
0

You're apparently calling the method before the first render cycle. The init handler runs before the component is rendered. Alternatively, you're modifying an element that causes a re-render and you're not waiting for that cycle to finish. To prove that this should generally work, I wrote this code:

<aura:application extends="force:slds">
    <div aura:id="myElement">
        ...
    </div>
    <lightning:button onclick="{!c.myFunction}" label="Do it!" />
</aura:application>

....

({
    myFunction: function(component, event, helper) {
        const myElement = component.find("myElement");
        $A.util.addClass(myElement , "hello-world");
    }
})

....

.THIS.hello-world {
    background: black;
    color: white;
}

....

If you put this in to a Lightning Application, you'll see it works. Therefore, this is just a timing issue. Your code here is just fine, it's just when you're calling the method that's incorrect.

4
  • Thanks @sfdcfox. In my project I won't be using Lightning Application, so I think I'll just need to find a creative way around this. Appreciate you explaining the timing aspect of this.
    – Matt Smith
    Commented Jun 24, 2020 at 20:27
  • @MattSmith A Lightning Component uses the same idea, it's just that an App is a stand-alone component.
    – sfdcfox
    Commented Jun 24, 2020 at 21:17
  • Thanks. It's not specified in my example, but I'm looking in sessionStorage for a value if it's there or not, then firing a method on doInit. It sounds like that's not possible because doInit is firing before the HTML renders.
    – Matt Smith
    Commented Jun 24, 2020 at 22:31
  • 1
    @MattSmith Yep. That's the gist of it. By the way, have you looked at my example of a sessionStorage-backed value provider? It allows you to build something like this fundamentally in your components. Alternatively, you can check the values in afterRender in a Custom Renderer.
    – sfdcfox
    Commented Jun 24, 2020 at 23:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .