2

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.

  • To give some additional info, I had tried to use <aura:if isTrue="{!not(empty(v.object.field))}"> and put the component inside the if statement, but it doesn't seem to work. My child component has to have a value in givenId to work. – Chance Jan 4 '18 at 17:11
  • Instead of multiple attributes use Object / Array whichever suits your need. – itzmukeshy7 Jan 7 '18 at 7:49
1

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
}
  • Would the childComponent need to have a init handler, or would that just be handled by the reference in the parent: [childComponent.methodOnChild(data);]? – Chance Jan 9 '18 at 15:09
  • 1
    You need init handler to load code when your component initializes childComponent.methodOnChild(data); just executes a method after the component has been loaded, so it is your decision if to implement an init handler – Itai Shmida Jan 9 '18 at 15:37
  • How do I get the results into the <aura:attribute name="picklistValues" type="Object" />? I am accustomed to action.setCallback using var list = response.getReturnValue(); component.set("v.component, list); Would I be able to use the callback? Would it be childComonent.setCallback? – Chance Jan 9 '18 at 17:56
  • please explain why do you need this callback? what are you trying to achieve? – Itai Shmida Jan 9 '18 at 20:06
  • I would like my child to return a list that populates an aura:attribute in the parent. How can I accomplish that? I'm sorry if my understanding is too limited. – Chance Jan 9 '18 at 20:29
0

I made a method to use as a utility for making toast messages

<aura:component description="AuraUtils">
<aura:method name="showToast" action="{!c.showToast}"  description="Used to show a toast message" >
    <aura:attribute name="title"    type="String"   description="title of toast" />
    <aura:attribute name="message"  type="String"   description="message inside of the toast"/>
    <aura:attribute name="type"     type="String"   description="error,warning,or success" />
    <aura:attribute name="mode"     type="String"   description="sticky, dismissible, or pester" />
</aura:method>

controller

showToast : function(component, event, helper) {
    var params = event.getParam('arguments');
    if (params) {
        var title = params.title;
        var message = params.message;
        var type = params.type;
        var mode = params.mode;
        helper.showToast(component, helper, title, message, type, mode);
    }
}

helper

showToast : function(component, helper, title, message, type, mode) {
    //helper.closeQuickActionPanel();
    let resultsToast = $A.get("e.force:showToast");
    let params = { "title": title, "message": message , "mode": mode, "type" : type};
    console.log('AuraUtils showToast params', params);
    resultsToast.setParams(params);
    resultsToast.fire();
}

I can call it like this

var AuraUtilsCmp = component.find("AuraUtils");
                if (AuraUtilsCmp) {
                    AuraUtilsCmp.showToast("", 'test message', 'message', "dismissible");
                }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.