17

If I have two functions foo() and bar() in my Lightning component controller, how can I call one function directly from another function, without having to queue it up through $A?

Here's a sample controller setup:

({
    bar : function(component, event, helper) {
        // Do something cool
    },
    foo : function(component, event, helper) {
        // How do I call bar() from here?
    }
})

5 Answers 5

18

I think that the better approach would be to try to extract whatever it is that you need to call in that controller function into the helper and call the helper. The helpers exist to enable sharing code within a component. Do you have a use case where that wouldn't work?

Just for fun, inspecting the action object the following would work:

var action = component.get("c.bar");
action.$meth$();

Obviously don't do that! :)

1
  • Thanks, Peter. This may very well be the right approach. However, it just seemed cumbersome to me, that if I wanted to reuse code across functions, I would always have to pass helper as a parameter. Maybe this is just how it needs to be with Lightning, and I guess I just miss being able to call other static or member methods from another static or member method in Apex.
    – Marty C.
    Commented Nov 7, 2014 at 3:17
13

Lightning has been enhanced with a way to call a controller function after this question was posted in 2014.

You can declare the target controller function using the tag aura:method like below:

<aura:method name="barMethod" action="{!c.bar}" description="bar controller function" />

Then you can reference it on the controller:

({ bar : function(component, event, helper) { // Do something cool }, foo : function(component, event, helper) { // This is how you call bar() from here component.barMethod(); } })

If you need to pass a parameter other than those 3, you'll need to add an aura:attribute tag to the aura:method:

<aura:method name="barMethod" action="{!c.bar}" description="bar controller function"> <aura:attribute name="param1" type="the type" default="default value" /> </aura:method>

And the bar function needs to extract the parameter from the event like below:

var params = event.getParam( 'arguments' ); if( params ) { var param1 = params.param1; // rest of the code here }

See more at: Calling Component Methods

2
  • This is definitely designed as a public API, which the component should normally use... but it works! Commented Mar 28, 2017 at 22:02
  • 1
    I guess this should be the accepted answer Commented Jun 12, 2023 at 6:58
9

This is why Helpers exist as Peter correctly outlined above. We do know that there are a number of patterns in Aura that appear heavyweight but most have a logical justification. This specific case is one where I have a hard time explaining the why and we do have plans to streamline a number of things like this in the future (no ETA but I can say that we have the same complaint inside of Salesforce R&D).

You do not pass helper directly - Aura does that for you - this is just dependency injection which is a common pattern in many frameworks e.g. Angular.js

2
  • Thanks for the note, Doug. Am I correct in understanding that I can call helper functions without actually passing helper as a parameter?
    – Marty C.
    Commented Nov 7, 2014 at 15:31
  • Can you add the explanation of why this isn't possible or what the current best way to handle this is?
    – Keith C
    Commented Mar 9, 2017 at 14:49
5

Reworking your specific sample:

myController.js

({
    bar : function(component, event, helper) {
        helper.doSomethingCool();
    },
    foo : function(component, event, helper) {
         helper.doSomethingCool();
    }
})

myHelper.js

({
    somethingCool : function() {
        // Do something cool
    }
})
2
  • can you prescribe how to call one Helper JS function from another Helper JS function in myHelper.js ?
    – VarunC
    Commented Oct 9, 2015 at 18:14
  • 3
    If you are already inside another method in your helper you can simply use this.someOtherHelperMethod() - this === helper inside of helper methods Commented Oct 9, 2015 at 22:46
-1

In the case where you have Button1 that on click calls foo and Button2 that on click should do all that foo does and something else you'd call it like this:

bar: function(component, event, helper) {
    //do bar
    component.get("c.foo").run();
}

You must log in to answer this question.

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