9

I was hoping to set up an abstract component with some useful markup (custom spinner and notifier components in this instance) that could be extended by other components.

The structure would be:

AbstractComponent AbstractMarkup Body of Extending Component

However, when I call a method on the abstract component, it is unable to find any of it's own components. I think this is an error, because it makes the abstract component much less useful.

Here is code that will replicate the issue:

TestFindAbstract.cmp

<aura:component abstract="true" extensible="true" >
    <ui:outputText value="hey" aura:id="myText"/>
    {!v.body}
</aura:component>

TestFindAbstractHelper.js

({
    changeText : function(component) {
        var text = component.find("myText");
        text.set("v.value","New Text");
    }
})

Now, the extending class:

TestFind.cmp

<aura:component extends="c:TestFindAbstract">
    <lightning:button label="Press Me" iconName="utility:download" iconPosition="left" onclick="{!c.changeText}" /> 
</aura:component>

TestFindController.js

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

I would have expected the extending class to call the method on the abstract class, find the component and change the value. Instead, I get the very diplomatic error message:

This page has an error. You might just need to refresh it. Action failed: c$TestFind$controller$changeText [Cannot read property 'set' of undefined] Failing descriptor: {c$TestFind$controller$changeText}

Any insights would be appreciated!

  • 1
    Maybe this: "To do that, the concrete component must be retrieved (component.getConcreteComponent()) and its helper called. If the sub component does implement the preLoadProcess then its implementation will be called." - developer.salesforce.com/blogs/developer-relations/2015/03/… - Honestly just a shot in the dark :0 – Eric Feb 3 '17 at 5:13
  • Yes, I was thinking that would just call the sub component, but I'll give it a shot and see how it goes. Shots in the dark very welcome!! – Caspar Harmer Feb 3 '17 at 5:33
  • So, yes, that calls the child component... which calls the parent component... which... you get the picture :). The problem seems to be that it's not adding the component in the abstract component to the body[] array. Perhaps that's by design, but that would be a little sad. – Caspar Harmer Feb 3 '17 at 5:39
  • @DougChasman any ideas? – Caspar Harmer Feb 3 '17 at 5:39
  • So it worked yea. Now the recursion is the bug lol. Kidding – Eric Feb 3 '17 at 5:40
5

You can solve this in two ways:

  1. Since the ui:outputText belongs to the extensible component, you need to get hold of the super component; then from there find and set ui:outputText's value.

With the above change, your helper will look like this:

({
    changeText : function(component) {
        var text = component.getSuper().find("myText");
        text.set("v.value","New Text");
    }
})
  1. Define an aura:attribute in the extensible component, and set its value in the concrete component.

TestFindAbstract.cmp:

<aura:component abstract="true" extensible="true" >
    <aura:attribute name="text" type="String" default="hey" />
    <ui:outputText value="{!v.text}" aura:id="myText"/>
    {!v.body}
</aura:component>

TestFindCmp.cmp:

<aura:component extends="c:TestFindAbstract">
    <lightning:button label="Press Me" iconName="utility:download" iconPosition="left" onclick="{!c.changeText}" /> 
</aura:component>

TestFindCmpController.js:

({
     changeText : function(component, event, helper) {
         component.set("v.text",'New');
    }
})
  • 2
    Crikey! You are right! I thought that there was no point in calling get super as I was already in the context of the super component... Obviously not. Thank you sir, excellent answer ( I tried the first option - that's what I was after) – Caspar Harmer Feb 3 '17 at 18:24
  • One further update... I think I did actually try getSuper() at one point, but I've now found that mavensmate was silently failing to save - even though it appeared to save. Not sure if this is on Mavensmate's end or Salesforce's end. Anyway, the moral of the story is re-auth frequently! – Caspar Harmer Feb 3 '17 at 18:49

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.