You may come across with buiness need to create components dynamically from controller side JavaScript. In lightning, you may also face issues when child component ‘init’ method is called before parent’s ‘init’ method. It causes child component to fail to get the attributes required which is passed through parent component. To solve this problem, you can use dynamic component creation. Below dynamic child component creation has been explained detail to teach you – how to do it.

Creation of child component

Let’s assume you have form on which user needs to enter his personal detail. Form contains fields such as First Name, Last Name, Register Date, Country and Submit button

‘UserForm’ is parent component. ‘DateComponent’ is child component which displays Register Date in ‘Month, yyyy’ format. You want to create ‘DateComponent’ dynamically through ‘UserForm’ controller JavaScript.

UserForm Markup

<aura:component >
<aura:attribute name="fistName" type="String"/>
<aura:attribute name="lastName" type="String"/>
<aura:attribute name="SampleDate" type="Date"/>
<aura:attribute name="country" type="String"/>
<aura:attribute name="dateComp" type="Aura.Component" />
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<div><h3 class="slds-section__title slds-m-top--medium slds-m-bottom--medium">Employee Information </h3></div>
<div class="slds-form-element gu-form-group">
<div class="slds-form-element__control">
<lightning:input class="slds-form-element__label" type="text" label="First Name" name="firstName" />
</div>
<div class="slds-form-element__control">
<lightning:input class="slds-form-element__label" type="text"
label="Last Name" name="lastName" />
</div>
<div class="slds-form-element__control">
{!v.dateComp}
</div>
<div class="slds-form-element__control">
<lightning:input class="slds-form-element__label" type="text" label="Country" name="country" />
</div>
<div class="slds-form-element__control">
<lightning:button variant="brand" label="Submit" onclick="{! c.submit }" />
</div>
</div>
</aura:component>

DateComponent Markup:

<aura:component >
<aura:attribute name="RegisterDate" type="String"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<lightning:input name="Register" label="Last Register" type="Month" value="{!v.RegisterDate}" class="slds-form-element__label"/>
</aura:component>

You can see ‘dateComp’ attribute has been created in parent component markup as ‘Aura.Component’ type. It is used to hold properties of dynamic component created. Notation ‘{!v.dateComp }’ is used to specify the location of the dynamic component need to be rendered.

How to create dynamic component?

You can create dynamic component in ‘doInit’ method of the parent component. Let’s have the look at the controller logic.

UserForm controller

doInit : function(component, event, helper) {
var today = new Date();
component.set('v.SampleDate',"2017-02");
$A.createComponent("c:DateComponent", {
"aura:id" : "registerDate",
"RegisterDate" : component.get("v.SampleDate")
}, function(newCmp,status,errorMessage) {
if (component.isValid()) {
if(status == "ERROR") {
console.log('Error Message--',errorMessage);
}
component.set("v.dateComp", newCmp);
}
}

$A.createComponent is the method used to create component dynamically. You need to pass aura: id as one of the parameter. You also require passing ‘RegisterDate’ as a parameter. Make sure, you are also creating ‘RegisterDate’ attribute in child component markup. You can assign newcomponent to ‘dateComp’ attribute as above code,

component.set("v.dateComp", newCmp);

In above line, new component has been assigned to ‘dateComp’ attribute. This will make dynamic component to render on markup where you have specified as {!v.dateComp}. How can you access the attribute of child component? Below code snippet which fetchs Register Date value on click of ‘Submit’ button.

Accessing child component attribute Parent

submit : function(component, event, helper) {
var dateComponent = component.get("v.dateComp");
console.log('Child component attribute value :',dateComponent.get("v.RegisterDate"));
}

You need to get the properties of ‘dateComp’ attribute as shown in first line of ‘submit’ method. Since dateComp holds the child component properties, you can get the Register Date as specified in the second line. This also resolves the issue of child ‘init’ getting called before parent’s ‘init’ method. As child will be created as instructed in the parent’s controller JavaScript.

Happy Coding!