4

Here is the code my for my Helper class which is used to create a new case. I'm trying to set the Id of the newly created case to the attribute on the component itself. The 3 and 4 are showing undefined in the console but 1 and 2 are showing the ID properly. They are also displaying in the console in this order: 3,4,1,2

Helper Class

createCase: function(component, c) {
var action = component.get("c.saveCase");
action.setParams({
    "c": c
});

action.setCallback(this, function(response){
    var state = response.getState();
    if (component.isValid() && state === "SUCCESS") {
        var id = response.getReturnValue();
        component.set("v.caseId",id);
        console.log("1-" + component.get("v.caseId"));       
    }

    console.log("2-" + component.get("v.caseId"));
});

console.log("3-" + component.get("v.caseId"));
$A.enqueueAction(action);
console.log("4-" + component.get("v.caseId"));

Component code:

<aura:attribute name="caseId" type="String" />

<aura:attribute name="newCase" type="Case"
    default="{ 'sobjectType': 'Case', 
   'Subject': '',
   'Activity__c': '',
   'Reason': '',
   'Contact': '',
   'Description': '',
   'Origin' : '',
   'FOA__c' : '',
   'Project__c' : ''
   }"/>

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

Javascript Controller

clickCreateCase: function(component, event, helper) {

var newCase = component.get("v.newCase");
console.log("Create case: " + JSON.stringify(newCase));
helper.createCase(component, newCase); 
}

Apex Controller

    @AuraEnabled
    public static String saveCase (Case c){
        upsert c;
        return String.ValueOf (c.Id);
    }
11
  • would you mind putting full code here because this looks weird Commented Oct 17, 2016 at 21:37
  • @MohithShrivastava I edited the code to clean it up and include other code.
    – Alex
    Commented Oct 17, 2016 at 21:41
  • can you post your apex controller? to see what saveCase method returns
    – Rao
    Commented Oct 17, 2016 at 21:42
  • 1
    I assume order of execution is due to the way lightning handles server response,"The solution to staying responsive while waiting is that server responses are handled asynchronously. "trailhead.salesforce.com/en/lex_dev_lc_basics/… , I feel the OOE is the same reason why you get undefined because the client side controller executes 3 and 4 before the async request is completed, it does not have value back from the server side and hence throws an undefined
    – Rao
    Commented Oct 17, 2016 at 22:36
  • 4
    Mohit, what Rao said is correct.Only the function passed as the callback will be called(similar to any other ajax request) when client gets the response from the server.So the order 3,4,1,2 is correct.
    – Praveen
    Commented Oct 18, 2016 at 5:01

1 Answer 1

1

This has basically been answered in the comments, but to sum up: This is a normal JavaScript behaviour not restricted to Lightning. Functions that will require time are executed in an asynchronous and non-blocking manner. The parent function takes a callback as a parameter but does not execute it; then it continues to execute subsequent lines in sequence. After an undetermined amount of time, when the results of the request come back, the callback is executed.

If you wanted to run some code only after the request is completed, you'd have to ensure that code executes within the callback. In JavaScript it used to be common to have callbacks inside of callbacks ad nauseam ("callback hell") for exactly this reason. There are many better strategies now including Promises which you can read up on. In Lightning another possible approach is to fire an event at the end of the callback, and then let the handler of that event take care of what needs to be done next.

2
  • Thanks for the explanation. I've learned a lot about the inner workings of JavaScript/jQuery. I have a question in response to your explanation. Lets say that I have a callback in my initialization and only one callback. Is there any way to hold the page load so that the page isn't loading without data and then redrawn? I asked a question detailing this question with code: link
    – Alex
    Commented Nov 2, 2016 at 20:13
  • I think Lightning is not designed for you to be able to purposely hold up the page load. And frankly any rendering solution requiring jQuery is really not a good match for a Lightning Component. In any case it seems that what you want to delay is the execution of the DataTable function, not the loading of the resources themselves. In theory you could use Promises to ensure a piece of code is run only after both the init call back and the scripts are loaded.
    – Charles T
    Commented Nov 3, 2016 at 16:08

You must log in to answer this question.

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