2

I'm teaching myself Lightning components, and I'm playing around with the ui:button - namely, sending a request to the apex controller to update a specific Contact record.

Unfortunately, I'm having this weird issue with the ui:button. Whenever I click on it, the Javascript Console says that the associated controller method (and hence the helper method) is firing repeatedly. This happens until the page crashes. The Apex Controller method never gets reached.

If I DON'T fire the helper method, there is no issue, so I think its something to do with that. I've looked at the Quick-Start solution in the developer guide, but I had a bit of trouble understanding it - I'm still fairly new to the concept of callbacks and asynchronous code.

My component looks like this (skipping a few bits):

<aura:attribute type="String" name="parentId"/>  
<aura:attribute name="parent" type="Contact"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />  

<ui:button label="Submit"
    class="slds-button slds-button--neutral"
    labelClass="label"
    press="{!c.updateParent}"/>

My controller looks like this:

({
doInit : function(component, event, helper) {
   //Get family data
   helper.getParent(component);
   helper.getChildren(component);
},//Delimiter for future code

updateParent : function(component, event, helper) {
    console.log('controller - updateParent called');
    helper.updateParent(component);
},
})

My helper file looks like this:

({
getParent: function(component) {
    var action = component.get("c.getParent");
    action.setParams({"parentId": component.get("v.parentId")});
    action.setCallback(this, function(response) {
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            component.set("v.parent", response.getReturnValue());
            console.log(response.getReturnValue());
        }
    });
    $A.enqueueAction(action);
},

updateParent: function(component) {
    console.log('helper - updateParent called');
    console.log(component.get("v.parent"));
    var action = component.get("c.updateParent");
    action.setParams({"parent": component.get("v.parent")});
    action.setCallback(this, function(response) {
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            console.log(response.getReturnValue());
        }
    });
    $A.enqueueAction(action);
},
4

The rule of thumb in lightning is never name your methods with the same name .

1.Make sure your apex controller methods is never similar to your one of the JS controller methods name

2.Similarly make sure your helper methods name are not similar to the Javascript controller methods name

3.Also make sure helper method names do not conflict with apex controller method name.

Now looking into your code the helper and controller has same method name "updateParent" which is an issue and lightning component underlying code from salesforce is not smart enough to resolve the conflict I believe .

Change the method names in the helper to something different and you should be good .

  • Just had the same problem, tried to figure out for 3 days !! That just solved it. – osos9 May 1 '19 at 12:20
2

As Mohit suggested, changing the method name of the controller and @AuraEnabled method would solve the issue.

Why this is happening?

Lightning Component has two value providers:

1.v(view) - A component’s attribute set. This value provider enables you to access the value of a component’s attribute in the component’s markup.

2.c(controller) - A component’s controller, which enables you to wire up event handlers and actions for the component

To invoke @AuraEnabled method, we need to do component.get("c.methodName") - so we need use value provider c to get the @AuraEnabled method's reference.

So, if you are using the same name for the controller method(client side) and Aura method, you get the reference of the controller method not the aura method you wanted.Which is inturn causes the controller method to be invoked recursively which causes the page to crash.

controller:

({
doInit : function(component, event, helper) {
   //Get family data
   helper.getParent(component);
   helper.getChildren(component);
},//Delimiter for future code

updateParent : function(component, event, helper) {
    console.log('controller - updateParent called');
    helper.updateParent(component);
},
})

helper:

updateParent: function(component) {
    console.log('helper - updateParent called');
    console.log(component.get("v.parent"));
    var action = component.get("c.updateParent"); // you get the client side controller method's reference not the aura method's.
    action.setParams({"parent": component.get("v.parent")});
    action.setCallback(this, function(response) {
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            console.log(response.getReturnValue());
        }
    });
    $A.enqueueAction(action); // calling the controller method again and again
},

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.