[SalesForce] Aura:Method with Parameters / Conditional Component Instancing

I'm trying to make a component that can be used for many different scenarios. So I want to be able to use it in parent components. The idea is that the parent component would be used to create records and the child component would find related records based on criteria. Thus, I need the child component to only run/be instanced when I have a specific field populated in Lightning Data.

I have looked at a lot of references for Aura:Method, but I don't see/understand how to pass parameters from the parent to the method.

Here is a sample set of code that simplifies what I am trying to do. First the Method.

<aura:component controller="serverSideController" access="global">

<!-- Define the component as a Method to be called easier -->
<aura:method name="myMethod">

    <aura:attribute name="callback" type="Function" />

    <aura:attribute name="givenId" type="String" />
    <aura:attribute name="field2" type="String" />
    <aura:attribute name="field3" type="String" />
    <aura:attribute name="field4" type="String" />
    <aura:attribute name="field5" type="String" />

    <aura:attribute name="picklistValues" type="Object" />

    <!--
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    -->

</aura:method> 

myMethodController

({
echoJunction : function(component, event) {
    var params = event.getParam('arguments');
    var callback;
    if (params) {
        callback = params.callback;
    }

    var action = component.get("c.junctionObjectRelLookupController");

    //Pass the parameters to the APEX class
    action.setParams({
        givenId: component.get("v.givenId"),
        givenIdFieldName: component.get("v.field2"),
        junctionObjectName: component.get("v.field3"),
        destinationObjectFieldName: component.get("v.field4"),
        destinationObject: component.get("v.field5")
    });

    //Give the results
    action.setCallback(this, function(response) {
        var state = response.getState();
        if (state === "SUCCESS") {
            //Return doesn't work for async server action call
            console.log("From server: " + response.getReturnValue());

            //call the callbackpassed into aura:method
            //I gave up right here and decided to ask how to proceed
        }

        var list = response.getReturnValue();
        component.set("v.picklistValues", list);
    })
    $A.enqueueAction(action);
}

And finally the serverside controller:

public class serverSideController {
@AuraEnabled
public static List<String> getRecordsIntoList(String givenId, String field2, String field3, String field4, String field5){
    //logic here        
    return pickListValuesList;
}

So, if I am creating a record in a parent controller, how do I pass the parameters to the aura:method, and how do I get the values back in?

I had used something like this to pass the parameters and to have somewhere to hold the results:

<aura:attribute name="results" type="Object" />
<c:junctionObjectRelationshipLookup givenId="{!v.object.field}" 
                                        field2="Specific String" 
                                        field3="Specific String"
                                        field4="Specific String"
                                        field5="Specific String" 
                                        picklistValues="{!v.results}" />

The key here is that my child component needs the givenId to function. Well, it needs all of them, clearly. I also want to use it twice in the same component, and I want the different instances to have different values in the other field names.

Best Answer

I am not sure you have configured correctly the components.

In your child component (lets call it childComponent) you need to define the aura:method and give it an action with a javascript method name, also I think Function type of attribute is not supported, but anyway I would make this a general object and pass it a json object so it can change easily as you please:

<aura:method name="methodOnChild" action="executeFromParent">
    <aura:attribute name="data" type="Object" />
</aura:method>

After that, to execute the method - in your parent component you need to identify your childComponent so you can give it an aura:id when you are instantiating it, for example (you can do that in other ways):

<c:childComponent aura:id="childComponentId" />

Then in your parent component controller - you need to create the params to return, and then get the childComponent and execute the method like this:

var data = {
                givenId: component.get("v.givenId"),    
                field2: component.get("v.field2"),
                field3: component.get("v.field3"),
                field4: component.get("v.field4"),
                field5: component.get("v.field5"),
                picklistValues: component.get("v.picklistValues")
            };

var childComponent = component.find("childComponentId");
childComponent.methodOnChild(data);

Finally on your childComponent you need to have the javascript method on your controller (the aura:method will call this method):

executeFromParent : function (component, event, helper) {
    var data = event.getParam('data');  
    // now data contains your json - do whatever you want with it
}
Related Topic