• Pawan Kumar 407
  • NEWBIE
  • 0 Points
  • Member since 2019

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
    Questions
  • 1
    Replies
The Lightning Components Developer Guide warns about using the same name for client and server controller actions:
Use unique names for client-side and server-side actions in a component. A JavaScript function (client-side action) with the same name as a server-side action (Apex method) can lead to hard-to-debug issues.
I was unlucky enough to miss this tip before I debugged one of those hard-to-debug issues. To prevent others from making the same mistake, I wanted to share my debug path in case you miss the memo about naming conventions and run into similar symptoms:

PricingTool.cmp
My component contains a button that runs a client controller action named "c.getPricing"

<pre>
<aura:component controller="ServerController">
  <aura:attribute name="products" type="ServerController.ProductPrice[]"></aura:attribute>
  <ui:button aura:id="buttonGetPricing" label="Get Pricing" press="{!c.getPricing}"></ui:button>
</aura:component>
</pre>

PricingToolController.js
The controller action calls a helper action with the same name: "hlp.getPricing"

<pre>
({
    getPricing: function(cmp,evt,hlp){
        console.log('in c.getPricing');
        hlp.getPricing(cmp,hlp);
    }
})
</pre>

PricingToolHelper.js
My helper attempts to call a server-side action "c.getPricing", which is the same name as the client-side action "c.getPricing"

<pre>
({
    getPricing : function(cmp,hlp)
    {
        console.log('in hlp.getPricing');
        var action = cmp.get('c.getPricing');
        var products = cmp.get('v.products');
        action.setParams({productList : products});
        action.setCallback(this,function(res){
            console.log('in hlp.getPricing callback');
            var state = res.getState();
            console.log('hlp.getPricing ' + state);
            if (state === "SUCCESS") {
                var pricing = JSON.parse(res.getReturnValue().body);
                console.log(pricing);
            }
        });
        $A.enqueueAction(action);
    },
})
</pre>

ServerController.cls
The server code successfully passes unit testing, but when launched from my Lightning Component helper class, no "/aura" logs are created on the server, indicating the server code is never touched.

<pre>
public class ServerController{

    @AuraEnabled
    public static Response getPricing(List<ProductPrice> productList) {...}
}
</pre>

Back To The Client...
So the server action is never run, and my javascript console is growing a fearsome loop of the following log lines:
 
in c.getPricing             # client controller action triggered
in hlp.getPricing           # helper action triggered
in hlp.getPricing callback  # callout to "c.getPricing" triggered
hlp.getPricing SUCCESS      # callout successfully returned
undefined                   # the results of res.getReturnValue() are empty
in c.getPricing
in hlp.getPricing
in hlp.getPricing callback
hlp.getPricing SUCCESS
undefined

The Moral of this Story
When the helper attempts to "get" a server action from the component, it receives the client action instead, because they use the same name. This causes an endless loop on the client, where the controller executes itself again and again via the helper's action call. The callback won't throw any errors and happly continues with a "SUCCESS" state.

The fix to this all, of course, is quite simple.

ServerController.cls
First change the name of the server controller action:

<pre>
// public static Response getPricing(...) {...}
public static Response getServerPricing(...){...}
</pre>

PricingToolHelper.js
Then update the helper reference to the server controller:

<pre>
// var action = cmp.get('c.getPricing');
var action = cmp.get('c.getServerPricing');
</pre>

Happy Lightning Development!
  • March 27, 2016
  • Like
  • 1