[SalesForce] action.setCallback not getting executed after $A.enqueueAction(action);

I have been stuck on this problem for two days now and it doesn't seem like I can figure this one out by myself. Need some help from the community…

I have been trying to get the return value from an apex method. Normally this can be done by calling the $A.enqueueAction(action) and this will then call the action.setCallBack method to give me back the return value of my apex method. By default, the return value is stored in response.getReturnValue().

But with my code, my $A.enqueueAction(action) did get executed but my action.setCallBack method never got executed. Without action.setCallBack method being called, I had no way of obtaining the return value from my apex method. Anyone here seen this problem before?

Here's my helper controller:

// EstimatorCalendarHelper.js
callServer : function(component, event, helper, startDateTime) {
    // some more code here 
    var action = component.get("c.convertTheLead");    
    action.setParams({ "eventRecord" : JSON.stringify(component.get("v.newEvent")), "eventStartDateTime" : eventStartDateTime, "eventEndDateTime" : eventEndDateTime });
    action.setCallback(this, function(response) {            
        var state = response.getState();
        if (state === "SUCCESS") {     
            var oppID = response.getReturnValue();
            component.set("v.oppID", response.getReturnValue());
        } 
        else {               
            console.log(state);
        }          
    });             
    $A.enqueueAction(action);  
} 

Here is my client side controller:

// EstimatorCalendarController.js
handleValueChange : function(component, event, helper) {

   $('#calendar').fullCalendar({           
        // some code here
        select: function(startDate, endDate) {
            // some code here                           
            $("#eventContent").dialog({ modal: true, 
                                       width:750,
                                       buttons: {
                                           "Save Appointment" : function() {
                                               helper.callServer(component, event, helper, startDate);
                                               $( this ).dialog( "close" );                                                           
                                           },                                                  
                                           Cancel : function() {
                                               $( this ).dialog( "close" );                                                       
                                           }
                                       }
                                    });               
                                  }
                        })

}   

Here is my component:

// EstimatorCalendar.cmp
<aura:component controller="CreateAppointmentController">
    <aura:attribute name="appointments" type="Event[]" />
    <aura:attribute name="oppID" type="String" />
    <aura:handler name="change" value="{!v.appointments}" action="{!c.handleValueChange}"/>        
    // Some more code here
</aura:component>

Here is my Apex Controller:

// CreateAppointmentController.apex
@AuraEnabled
public static String convertTheLead (String eventRecord, String eventStartDateTime, String eventEndDateTime) {
    Event newEventRecord = (Event)JSON.deserialize(eventRecord, Event.class);
    newEventRecord.StartDateTime = DateTime.valueof(eventStartDateTime);
    newEventRecord.EndDateTime = DateTime.valueof(eventEndDateTime);
    try {    
        insert newEventRecord;
    }
    catch (DMLException ex){
        system.debug( ex.getMessage());
    }         
    Database.LeadConvert lc = new Database.LeadConvert();
    lc.setLeadId(newEventRecord.WhoId);
    LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
    lc.setConvertedStatus(convertStatus.MasterLabel);
    Database.LeadConvertResult lcr = Database.convertLead(lc);
    Id oppId = lcr.getOpportunityId();
    String oppIDString = String.valueOf(oppId);
    return oppIDString;    
}   

Best Answer

I have a hunch it's because you're using jquery AND an external library that the order of operations is slightly outside of the lightning framework so your callback is not getting caught. See the following article:

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

My gut instinct is to wrap your callout with a getCallback, but I'm not 100% sure where you would wrap it when you're using that calendar library. Try wrapping the helper with something like this:

$A.getCallback(function() {
  helper.callServer(component, event, helper, startDate);
});

You can also use promises to get a little more granular control:

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

Related Topic