Is it possible to set the value of an aura component to an expression dynamically?

In Lightning, expressions come in two types:

  1. Propery Reference Values like {!v.myButtonLabel} which simply points to an attribute. For those, you can get the reference using cmp.getReference("v.myButtonLabel") and the values will be properly linked, i.e. the component will update when the value changes.

  2. Function Call Values like {!v.myAttr + 1} which contain an equation. All markup in a component is preprocessed on the server and Function Call Values are sent in a compiled version to the client. You can't create a new expression from JavaScript.


you can make the dynamically created component's attribute point to aura:attribute but not to an aura:expression.

The key here is to use cmp.getReference().

Like the one you used in your code cmp.getReference("c.handlePress") to dynamically attach component's controller method to ui:inputButton's press event.

You have to use "label": "component.getReference("v.myButtonLabel)" which enables an two-way binding i.e if attribute myButtonLabel value changes ui:inputButton's label also changes and vice verse.

Incase, if you don't want any kind of two-way binding in the component's label, you use cmp.get("v.myButtonLabel") instead of cmp.getReference("v.myButtonLabel").

Here's an example:

Component:

<aura:application access="global">
    <aura:attribute name="test" type="String" default="testBtn"/>
    <!-- change the value and ui:inputButton's label changes --> 
    <ui:inputText value="{!v.test}" label="Set label"/> 
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    {!v.body} 
</aura:application>

Controller.js:

({
    doInit : function(cmp,event,helper) {
        $A.createComponent(
            "ui:button",
            {
                "aura:id": "findableAuraId",
                "label": cmp.getReference("v.test"), // or cmp.get("v.test")
                "press": cmp.getReference("c.handlePress")
            },
            function(newButton){
                if (cmp.isValid()) {
                    var body = cmp.get("v.body");
                    body.push(newButton);
                    cmp.set("v.body", body);
                }
            }
        );

    },
})