[SalesForce] Standard aura:attributes and aura:method attribute

My question is in regards to the fact that I need to get a value from Child component to Parent component. I want to directly call a method from the parent to the child to obtain some data from that child component. All this is fine but the question I have is about the following scenario. It looks like I can't dynamically pass the value from a component attribute to an aura:method attribute one:

<aura:component description="ChildComp">

<aura:attribute name="lookUp" type="String" default="Just Me" />

<aura:method name="GetMessageFromChildMethod" action="{!c.getMessage}" access="public">
    <aura:attribute name="Name" type="String" default="{!lookup}" />
</aura:method>

Something like the code above will not work.

So, the "standard" component attribute I need is already in use with the child component and there are some operations around that particular attribute.

What I want to know is:

  1. There is any problem in me changing the "standard" attribute from the child component to an inner aura:method attribute one?

  2. Will this change affect the behavior of that particular "standard component" attribute?

  3. If all of the above is rubbish, how can I pass dynamic values to an aura:method attribute?, if possible?

Best Answer

The <aura:method> declaration belongs on the component receiving the call. The method is considered part of the public API for that component.

In your scenario, the method would be declared on the parent, which is inverted from the typical scenario where child-to-parent communication uses events and parent-to-child communication uses public methods. Your child component will need to receive a reference to its parent and store it in an attribute in order to make the method call. (See example below).

The presence of <aura:attribute> declarations as part of the <aura:method> is a little confusing. The method's attributes actually define the parameters of the function that's being declared, and are independent of the attributes of both the calling and receiving component. The parameters passed to an <aura:method> are always dynamic insofar as they are passed in JavaScript, not declared in markup.

The example in the <aura:method> documentation is illuminating. I'm adding a bit of outer structure here to clarify. In your scenario, the receiving component is the parent, and the calling component is the child, which has an attribute parent to hold a reference to its parent component.

Receiving Component Markup

<aura:component ...>
    <aura:method name="sampleMethod" action="{!c.doAction}" 
      description="Sample method with parameters"> 
        <aura:attribute name="param1" type="String" default="parameter 1"/> 
        <aura:attribute name="param2" type="Object" /> 
    </aura:method>
<aura:component>

Receiving Component Controller

({
    doAction : function(cmp, event) {
        var params = event.getParam('arguments');
        if (params) {
            var param1 = params.param1;
            // add your code here
        }
    }
})

Calling Component Markup

<aura:component ...>
    <aura:attribute name="parent" type="Aura.Component" />
    <aura:attribute name="childAttribute" type="String" />
<aura:component>

Calling Component Controller

When we invoke the <aura:method>, we specify the parameters as part of a JavaScript method call, rather than using Lightning value binds to establish them. It's more or less like any other method call. When we do this, we can source values from our (child) component's attributes, or from any other data source available in the context.

Here, we grab the value of a component attribute on the child and pass it as a parameter up to the parent, along with a static value.

myAction: function(component, event, handler) {
    var someOtherComponentReference = component.get('v.parent');

    someOtherComponentReference.sampleMethod(
        component.get('v.childAttribute'), 
        {'foo': 'bar'}
    );
}

See Calling Component Methods.