1

I created an aura component which dynamically inserts components based on component names passed to it and several similar component have been working fine till very recently when they stop. When the execution reaches the $A.createComponent line, the code just stops. The callback is not entered. No errors. The strangest part is a very impractical workaround i have found. If i copy the component i want to insert directly into a div in the html and make that div display:none;, then the component is inserted by the controller. The execution enters the callback and the component is inserted. If i remove display:none; then the component appears twice. Below is a two simplified versions, one that does not work and one that does work but is not workable nor does it make any sense why it works. Code that does not work:

<aura:component implements="lightning:availableForFlowScreens,flexipage:availableForRecordHome,force:hasRecordId" 
                access="global">
    <aura:attribute name="utilityContainer" type="Aura.Component[]"/>
    <aura:handler name="init" value="{!this}" action="{!c.init}" />
    <aura:attribute name="recordId" type="String" />
    <aura:attribute name="caseId" type="String" />
    <div id="id">
        {!v.utilityContainer}
    </div>
    </aura:component>
<aura:component 
({
    init : function(component, event, helper) {
        var caseId = component.get("v.caseId");
            $A.createComponent(
                "c:meshSupport",
                    {
                        "recordId": caseId,
                    },
                    function(utility, status, errorMessage){
                        if (status === "SUCCESS") {
                            var container = component.get("v.utilityContainer");
                            container.push(utility);
                            component.set("v.utilityContainer", container);
                        }
                    }
            );
        }
        
    },})

If I change the cmp. file to the following, it works:

<aura:component implements="lightning:availableForFlowScreens,flexipage:availableForRecordHome,force:hasRecordId" 
                access="global">
    <aura:attribute name="utilityContainer" type="Aura.Component[]"/>
    <aura:handler name="init" value="{!this}" action="{!c.init}" />
    <aura:attribute name="recordId" type="String" />
    <aura:attribute name="caseId" type="String" />
    <div id="id">
        {!v.utilityContainer}
    </div>
    <div style="display: none;">
        <c:meshSupport recordId="{!v.caseId}"  />
    </div>
    </aura:component>
<aura:component 

I have tried inserting it from afterrender in the componentrenderer.js and i have tried using the after render event thinking it might have something to do with order of rendering. I have tried inserting a simple input box into the container first followed by the component. The input was successfully inserted. Does anyone have any idea at all what is going on?

3
  • Have you tried adding some console logging for where status !== "SUCCESS"?
    – Phil W
    Jul 31, 2020 at 16:46
  • Have you tried putting a try catch around the $A.createComponent, just to confirm if there's an error or not? Aug 1, 2020 at 20:49
  • Hi Phil, Hi Paul. Thanks for your comments. I had not tried either of these. I use Chrome dev tools and add break points or step forward. In version one it breaks before entering the callback and in version 2 all works fine. Just in case i have tried the try catch. Try block is entered but fails at $A.createComponent and skips the catch block entirely. I switched to debug mode and got the following error: Unsupported meshSupport method: Symbol(Symbol.toPrimitive). Returning undefined. I get it in version 1 and 2.
    – Dane
    Aug 2, 2020 at 11:31

2 Answers 2

0

Dane, I have tried to run ur code version 2. It seems that the error is that, It is unable to create component as if you check for status === "ERROR" and log the error you will get No COMPONENT named markup://c:meshSupport found

And also if possible please put some more info. about the question asked.

4
  • 1
    Hi Tushar, Thanks for the answer. I think you are right here. Ive looked into the compiling and rendering process and SF simply does not know to send the markup to the front end.
    – Dane
    Aug 6, 2020 at 7:28
  • Firstly I should be writting $A.createComponent('markup://c:meshSupport'...) not c:meshSupport. $A.createComponent('c:meshSupport'...) DOES works if the c:meshSupport component is added in a div with display:none because when SF compiles the code for the front end it knows that markup for c:meshSupport might be needed in the display none div therefore it must make this markup available.
    – Dane
    Aug 6, 2020 at 7:36
  • What this code is really supposed to do is render components dynamically using component names passed to it like so: $A.createComponent('markup://c:' + componentName ...) and this will never work because when SF compiles this serverside, componentName has no value so any required markup is not be sent along to the front end.
    – Dane
    Aug 6, 2020 at 7:42
  • My final comment to this is that I am told that one can add component references in the .design file like so <design:attribute name="component1" label="Component 1" required="true" datasource="meshSupport"/>. I have not tried this but if you have a similar use case, give it a try.
    – Dane
    Aug 6, 2020 at 7:46
0

Since i see that this question has been visited a number of times since I posted it, I'd like to let you know the workaround i use. So this is regarding the scenario in which you want to be able to pass a component name into an aura component so that the component of that name is truely added dynamically.

According to SF documentation simply adding a dependency tag should provide the frontend with the resources to render the component to be added.

<aura:dependency resource="markup://c:myComponent" type="COMPONENT"/>

This does not work for me. To ensure that markup is definitely available to the frontend I put the components in an aura:if tag with the variable permanently set to false.

<aura:if isTrue="{!v.library}">
    <c:myComponent1" />
    <c:myComponent2"/>
    <c:myComponent3"/>
</aura:if>

Originally i had this in a div set to display:none; but this a bad option because the components are actually in the mark up, not just available. They exist then in a div with display:none; obviously and in this case then the component JS is also run. When you use an aura if, the component does not appear in the markup and the js is not run accept in the event that you dynamically add it. I hope this is useful.

You must log in to answer this question.

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