Newer Version Available

This content describes an older version of this product. View Latest

Dynamically Creating Components

Create a component dynamically in your client-side JavaScript code by using the $A.createComponent() method. To create multiple components, use $A.createComponents().

Use $A.createComponent() instead of the deprecated $A.newCmp() and $A.newCmpAsync() methods.

Note

The syntax is:

1$A.createComponent(String type, Object attributes, function callback)
  1. type—The type of component to create; for example, "ui:button".
  2. attributes—A map of attributes for the component, including the local Id (aura:id).
  3. callback(cmp, status, errorMessage)—The callback to invoke after the component is created. The callback has three parameters.
    1. cmp—The new component created. This enables you to do something with the new component, such as add it to the body of the component that creates it. If there’s an error, cmp is null.
    2. status—The status of the call. The possible values are SUCCESS, INCOMPLETE, or ERROR. Always check the status is SUCCESS before you try to use the component.
    3. errorMessage—The error message if the status is ERROR.

Let’s add a dynamically created button to this sample component.

1<!--c:createComponent-->
2<aura:component>
3    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
4
5    <p>Dynamically created button</p>
6    {!v.body}
7</aura:component>

The client-side controller calls $A.createComponent() to create a ui:button with a local ID and a handler for the press event. The function(newButton, ...) callback appends the button to the body of c:createComponent. The newButton that’s dynamically created by $A.createComponent() is passed as the first argument to the callback.

1/*createComponentController.js*/
2({
3    doInit : function(cmp) {
4        $A.createComponent(
5            "ui:button",
6            {
7                "aura:id": "findableAuraId",
8                "label": "Press Me",
9                "press": cmp.getReference("c.handlePress")
10            },
11            function(newButton, status, errorMessage){
12                //Add the new button to the body array
13                if (status === "SUCCESS") {
14                    var body = cmp.get("v.body");
15                    body.push(newButton);
16                    cmp.set("v.body", body);
17                }
18                else if (status === "INCOMPLETE") {
19                    console.log("No response from server or client is offline.")
20                    // Show offline error
21                }
22                else if (status === "ERROR") {
23                    console.log("Error: " + errorMessage);
24                    // Show error message
25                }
26            }
27        );
28    },
29
30    handlePress : function(cmp) {
31        console.log("button pressed");
32    }
33})

c:createComponent contains a {!v.body} expression. When you use cmp.set("v.body", ...) to set the component body, you must explicitly include {!v.body} in your component markup.

Note

Creating Nested Components

To dynamically create a component in the body of another component, use $A.createComponents() to create the components. In the function callback, nest the components by setting the inner component in the body of the outer component. This example creates a ui:outputText component in the body of a ui:message component.

1$A.createComponents([
2    ["ui:message",{
3        "title" : "Sample Thrown Error",
4        "severity" : "error",
5    }],
6    ["ui:outputText",{
7        "value" : e.message
8    }]
9    ],
10    function(components, status, errorMessage){
11        if (status === "SUCCESS") {
12            var message = components[0];
13            var outputText = components[1];
14            // set the body of the ui:message to be the ui:outputText
15            message.set("v.body", outputText);
16        }
17        else if (status === "INCOMPLETE") {
18            console.log("No response from server or client is offline.")
19            // Show offline error
20        }
21        else if (status === "ERROR") {
22            console.log("Error: " + errorMessage);
23            // Show error message
24        }
25    }
26);

Destroying Dynamically Created Components

After a component that is declared in markup is no longer in use, the framework automatically destroys it and frees up its memory.

If you create a component dynamically in JavaScript and that component isn't added to a facet (v.body or another attribute of type Aura.Component[]), you have to destroy it manually using Component.destroy() to avoid memory leaks.

Avoiding a Server Trip

The createComponent() and createComponents() methods supports both client-side and server-side component creation. If no server-side dependencies are found, the methods are executed client-side.

A server-side controller is not a server-side dependency for component creation as controller actions are only called after the component has been created.

A component with server-side dependencies is created on the server. If there are no server dependencies and the definition already exists on the client via preloading or declared dependencies, no server call is made.

There’s no limit in component creation on the client side. You can create up to 10,000 components in one server request. If you hit this limit, ensure that you’re creating components on the client side in markup or in JavaScript using $A.createComponent() or $A.createComponents(). To avoid a trip to the server for component creation in JavaScript code, add an <aura:dependency> tag for the component in the markup to explicitly tell the framework about the dependency.

Tip

The framework automatically tracks dependencies between definitions, such as components, defined in markup. However, some dependencies aren’t easily discoverable by the framework; for example, if you dynamically create a component that isn’t directly referenced in the component’s markup. To tell the framework about such a dynamic dependency, use the <aura:dependency> tag. This ensures that the component and its dependencies are sent to the client, when needed.

The top-level component determines whether a server request is necessary for component creation.

Creating components where the top-level components don’t have server dependencies but nested inner components do is not currently supported.

Note