Salesforce Lightning Component will not update records via Apex call, freezes

5.9k Views Asked by At

Issue overview: Currently coding a Lightning Component to update records on a custom object. However, every time I trigger the update (via a ui:button), the page freezes and I don't see any errors in the debugger or console. Cannot for the life of me figure out why it won't work.

Context: The component has a number of dropdowns that are populated with records (with the label being the record name). Selecting a new value in the dropdown and hitting "Update" calls the below apex to change a custom field (Status__c = 'Ready') on the new selected item, and then updates the records that occur before it (Status__c = 'Complete). I do all of my security and update checks in another function during init, so you won't see that here (I can post the full code if needed). Just trying to get the update to work.

I would be eternally grateful if someone could show me the error of my ways :]. Always been a huge fan of stackoverflow and looking forward to contributing now that I finally signed up. Thanks for your time everyone!

Apex:

@AuraEnabled
public static void updateMilestones(String deployId,Boolean prodChanged,String newProdMile) {
    if( prodChanged == true && newProdMile != null ) {
        try {
            decimal newProdStepNum;
            List <Milestone__c> newReadyProdMile = New List<Milestone__c>();
            for(Milestone__c mil1:[SELECT id, Status__c, Step_Order__c FROM Milestone__c 
                                    WHERE Deployment__c = :deployID 
                                    AND id = :newProdMile LIMIT 1]){
                                    mil1.Status__c = 'Ready';
                                    newProdStepNum = mil1.Step_Order__c;
                                    newReadyProdMile.add(mil1); 
                                    }
            List <Milestone__c> prodMilesComplete = New List<Milestone__c>();
            for(Milestone__c mil2:[SELECT id, Type__C, Status__c FROM Milestone__c 
                                   WHERE Deployment__c = :deployID 
                                   AND Step_Order__c < :newProdStepNum 
                                   AND Type__c = 'Production' 
                                   AND Status__c != 'Complete'  
                                   AND Status__c != 'Revised']){
                                       mil2.Status__c = 'Complete';
                                       prodMilesComplete.add(mil2); 
                                   }
            update newReadyProdMile;
            update prodMilesComplete; 
        }
        catch (DmlException e) {
            throw new AuraHandledException('Sorry, the update did not work this time. Refresh and try again please!');
        } 
    }
}

Javascript:

updateMilestones : function(component, event, helper) {
    // update milestones server-side
    var action = component.get("c.updateMilestones");
    action.setParams({
        deployId : component.get("v.recordId"),
        newProdMile : component.find("prod-mile-select").get("v.value"),
        prodChanged : component.get("v.prodChanged")
    });

    // Add callback behavior for when response is received
     action.setCallback(this, function(response) {
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            // re-run the init function to refresh the data in the component
            helper.milesInit(component);
            // refresh record detail
            $A.get("e.force:refreshView").fire();
            // set Update Changed Milestones button back to disabled
            component.find("updateButton").set("v.disabled","true");
            // show success notification
            var toastEvent = $A.get("e.force:showToast");
            toastEvent.setParams({
                "title": "Success!",
                "message": "Milestones have been updated successfully."
            });
            toastEvent.fire();
        }
    });

    // Send action off to be executed
    $A.enqueueAction(action);
}

Component:

<aura:component controller="auraMilestonesController_v2" 
                implements="force:appHostable,flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickAction">
    <ltng:require scripts="{!$Resource.lodash}" afterScriptsLoaded="{!c.doInit}"/>
    <aura:attribute name="recordId" type="String" />
    <aura:attribute name="prodMiles" type="Milestone__c[]"/>
    <aura:attribute name="prodChanged" type="Boolean" default="false"/>
    <!-- FORM -->
    <div class="slds-col slds-col--padded slds-p-top--large" id="theform">
        <form class="slds-form--stacked">
            <!-- UPDATE BUTTON -->            
            <div class="slds-form-element">
                <ui:button aura:id="updateButton" label="Update Changed Milestones" press="{!c.updateMilestones}" 
                           class="slds-button slds-button--brand slds-align--absolute-center" disabled="true"/>
            </div>
            <hr style="color: #005fb2;background-color: #005fb2;"/>
            <!-- PRODUCTION -->
            <div aura:id="prod-section">
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="milestone">Production Milestone</label>
                    <div class="slds-form-element__control">
                        <div class="slds-select_container">
                            <ui:inputSelect aura:id="prod-mile-select" class="slds-select" change="{!c.prodChange}">
                                <option value="" >--Select One--</option>
                                <aura:iteration items="{!v.prodMiles}" var="m">
                                    <aura:if isTrue="{!m.Status__c == 'Ready'}">
                                        <option value="{!m.id}" selected="true">{!m.Name} ({!m.User_Name__c})</option>
                                    </aura:if>
                                    <aura:if isTrue="{!m.Status__c == 'Not Ready'}">
                                        <option value="{!m.id}">{!m.Name} ({!m.User_Name__c})</option>
                                    </aura:if>
                                </aura:iteration>
                                <option value="completeProdMile" id="completeProdMile">All Production Milestones Complete</option>
                            </ui:inputSelect>
                        </div>
                    </div>
                </div>
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="description">Description</label>
                    <div class="slds-textarea">
                        <aura:iteration items="{!v.prodMiles}" var="m">
                            <aura:if isTrue="{!m.Status__c == 'Ready'}">{!m.Description__c}</aura:if>
                            <!-- <aura:set attribute="else">All production milestones have been completed.</aura:set> -->
                        </aura:iteration>
                    </div>
                    <hr style="color: #005fb2;background-color: #005fb2;"/>
                </div>
            </div>
            <!-- END PRODUCTION -->
        </form>
    </div>
    <!-- / FORM -->
</aura:component>
2

There are 2 best solutions below

1
On BEST ANSWER

I believe the issue is that you have fallen into the all too common trap of naming both a client side and a server side controller method the same (updateMilestones in this case). Try changing the name of either to make them unique and I expect that will get you running.

Yes, there is a bug on this and many of us have been making a very loud noise about getting it fixed!

Also we have a very active Salesforce specific Stack Exchange forum over here https://salesforce.stackexchange.com/ that will get more attention - especially if you tag your posts with lightning-components (e.g. I have my account configured to send me an email alert on every post tagged with lightning-components, locker-service, etc).

0
On

That might be javascript causing the error.As it's difficult to solve without knowing the error, I would suggest you debug the error.

  1. Turn on debug mode. a. From Setup, click Develop > Lightning Components. b. Select the Enable Debug Mode checkbox. c. Click Save.

  2. In Chrome Developer Tools, check the "Pause on Caught Exceptions" checkbox in the Sources tab. This can often help finding the source of an issue. Other browsers may have similar options.

  3. Add a debugger statement if you want to step through some code. debugger; This is useful when you have a rough idea where the problem might be happening.

debugger

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/debug_intro.htm