13

I noticed after I turned on LockerService, a bunch of my components stopped working and it seems like all of them are choking with "cmp.find(...).getElement is not a function".

Reading some of the other questions posted here it seems like the error will be thrown if you try to get the inner content of an element that is not in your namespace, but I don't think that applies to my case.

I've created a small example that can be replicated easily, and I don't see any reason why getElement should not work here.

The following code just tries to call getElement until it no longer throws an error. Needless to say, it never happens.

TestApp.app

<aura:application implements="force:appHostable">
  <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <div aura:id="test">wow</div>
</aura:application>

TestAppController.js

({
    doInit : function (cmp, event, helper) {
        helper.getStuff(cmp, helper)
    }
})

TestAppHelper.js

({
    getStuff : function(cmp,helper) {
        try { 
            console.log(cmp.find("test").getElement());
        } catch (exc) {
            window.setTimeout($A.getCallback(function(){if (cmp.isValid()) {helper.getStuff(cmp,helper);}}), 500);
            return;
        }
        console.log("Finally it's available")
    }
})

1 Answer 1

6

To solve this, you need the help of renderer in this case. Since init handler long before DOM is rendered in the view, DOM won't be available which inturn causes error:

cmp.find(...).getElement is not a function

Refer this answer deep down it solves the same issue.

With afterRenderer in place, your code looks like below:

TestApp.app

<aura:application>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <div aura:id="test">wow</div>
</aura:application>

TestRenderer.js

({
    // Your renderer method overrides go here
    afterRender : function(cmp,helper){
        this.superAfterRender();
        console.log(cmp.find("test").getElement());
    }
})
3
  • 3
    Note that there is a caching bug here, however, where if you try to access the element before it's available in the init handler, it will be cached and continue to error on future calls. That issue is fixed in Spring '17, which is scheduled for release very soon (tomorrow or next week). For now you can remove all the calls that try to access the element before it's rendered to avoid the issue. Commented Feb 8, 2017 at 8:02
  • @TrevorBliss So component.find().getElement() in init handler will work after the fix is deployed?
    – Praveen
    Commented Feb 8, 2017 at 8:04
  • 4
    No it will return null instead of erroring, but future calls after the DOM is rendered will return the expected value. Commented Feb 8, 2017 at 8:20

You must log in to answer this question.

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