1

Is there a correct syntax to mimic the action.setParams({ serverParam: someValue } but for clientside methods?

Let's say I have the following:

component.find("myComp").fireMethod(
  "param1", 
  "param2", 
  "param3"
);

The current workaround I have if I don't need param2 is to declare it to null. Passing in params by explicitly stating them against an attribute like the below syntax from the docs doesn't work.

component.find('overlayLib').showCustomModal({
   header: "Application Confirmation",
   body: modalBody, 
   showCloseButton: true,
   cssClass: "mymodal",
   closeCallback: function() {
       alert('You closed the alert!');
   }
})

This was grabbed from the https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/ref_lightning_overlayLibrary.htm documentation.

My end goal is to do this:

component.find("myComp").fireMethod(
 param1: "param1", 
 param3: "param3"
);

Not this, which is the current workaround for custom component methods:

component.find("myComp").fireMethod(
  param1: "param1", 
  param2: null, 
  param3: "param3"
);

What am I missing? It would be nice to have a single custom component method defined and then only pass in the necessary parameters instead of passing in null a bunch of times for optional vars.

2
  • your example is from the lightning:overlayLibrary component, I do not understand what exactly do you want? what are you trying to achieve? Commented Oct 29, 2017 at 7:28
  • yes exactly - but you see how .showCustomModal() is a method on the overlay library? I want to be able to set parameters like that in my own component methods. I'll update for better clarity
    – tsalb
    Commented Oct 29, 2017 at 18:10

1 Answer 1

1

You're missing the curly braces (commonly called Object Notation). Using this, you have just one parameter in your method:

 doSomething: function(component, event) {
     var params = event.getParam("arguments").params;
     if(params.param1) { ...
     ...
 }

And for your aura:method:

<aura:method name="doSomething" action="{!c.doSomething}" 
  description="Do Something Special"> 
    <aura:attribute name="params" type="Object" default="{}" /> 
</aura:method>

Which you then pass using Object Notation:

 component.find("myComp").doSomething({
     param1: "value a",
     param3: function() {
         alert("You closed the dialog!");
     }
 });

Note the "extra" { and }: this causes all of the elements within to be built as an Object.


Actual demonstration code:

Component

<aura:component >
    <aura:method name="displayValues" action="{!c.displayValues}">
        <aura:attribute name="params" type="Object" default="{}" />
    </aura:method>
    <aura:attribute name="paramCount" type="Integer" />
    <aura:attribute name="params" type="Object[]" />

    <p>Number of parameters: {!v.paramCount}</p>
    <p>Parameters:</p>
    <ul>
        <aura:iteration items="{!v.params}" var="param">
            <li>{!param.key}: {!param.value}</li>
        </aura:iteration>
    </ul>
</aura:component>

Component Controller

({
    displayValues: function(component, event) {
        var params = event.getParam("arguments").params;
        var output = [];
        component.set("v.paramCount", Object.keys(params).length);
        Object.keys(params).forEach(function(v,i,a) {
            output.push({key: v, value: params[v]});
        });
        component.set("v.params", output);
    }
})

Sample Application

<aura:application extends="force:slds">
    <lightning:button label="1 Param" onclick="{!c.oneparam}" />
    <lightning:button label="4 Params" onclick="{!c.fourparams}" />

    <c:q197177c aura:id="myId" />   
</aura:application>

Sample Application Controller

({
    oneparam: function(component, event, helper) {
        component.find("myId").displayValues({
            hello: "world"
        });
    },
    fourparams: function(component, event, helper) {
        component.find("myId").displayValues({
            param1: "four",
            param2: "different",
            param3: "values",
            param4: "provided"
        });
    }
})
2
  • Yep, this makes sense. I was hoping to avoid this because then the signature in the component methods are impossible to read. For some of my methods which are 3-7 attributes, hiding them all in an object params makes it difficult to see which ones are optional. Would you happen to know a good pattern that lets both an object attribute (with multi param) but also maintain readability when looking at just the method signature?
    – tsalb
    Commented Oct 30, 2017 at 1:41
  • @tsalb Unfortunately, I don't think you can. The reason why is that JS doesn't support optional parameters, so there's no way to say someFunc(a,,b) or something like that. This is why Object Notation is heavily used in JavaScript libraries, because it allows you to specify the parameters you want in the order you want. The best you can do is include an example in the Design file and/or include information in the description of the method parameter.
    – sfdcfox
    Commented Oct 30, 2017 at 3:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .