• Donald Dedman
  • NEWBIE
  • 5 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 1
    Likes Given
  • 0
    Questions
  • 2
    Replies
In my company I was facing a scenario where I had to chain two Apex asynchronous calls:
First I needed to call myApexMethod1 which returns a result myResult
Secondly I needed to call myApexMethod2 but needed to provide myResult as a parameter to the method.


So this is the first version I coded :
 
({
    "myFunction" : function(cmp) {


        var action = cmp.get("c.myApexMethod1");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
               myResult = response.getReturnValue();
            }
        });
        $A.enqueueAction(action);


        var action2 = cmp.get("c.myApexMethod2");
	action2.setParams({ myParam : myResult });
        action2.setCallback(this, function(response) {
            var state2 = response.getState();
            if (state2 === "SUCCESS") {
               //Do something
            }
        });
        $A.enqueueAction(action);


    }
})

This code compiles well but there is a problem:
Since the calls are asynchronous, by the time we reach :
action2.setParams({ myParam : myResult });

it is not guaranteed that myResult is filled, because at that time nothing guarantees that myApexMethod1 has executed since it is asynchronous.

To avoid this behaviour, I decided to nest the second call inside the callback of the first method.
That gives the following code :
 
({
    "myFunction" : function(cmp) {


        var action = cmp.get("c.myApexMethod1");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {

               myResult = response.getReturnValue();

               var action2 = cmp.get("c.myApexMethod2");
	       action2.setParams({ myParam : myResult });
               action2.setCallback(this, function(response) {
                   var state2 = response.getState();
                   if (state2 === "SUCCESS") {
                        //Do something
                   }
               });
               $A.enqueueAction(action);

            }
        });
        $A.enqueueAction(action);

    }
})

I have tested it and it works.

But my question is:
Is it the proper way to chain these asynchronous calls?
Next time maybe I will have to chain a lot of asynchronous calls and this pattern does not look very clean?
Is there a better practice to chain these asynchronous calls?

 
All, I am a bit stuck to complete the challenge of the Apply Service Layer Principles in Apex trail.
I have created what has been requested and tested it successfully but I keep getting the following error: 

Challenge Not yet complete... here's what's wrong: 
The Apex service does not appear to be closing cases correctly with the specified reason.

Any idea on how to debug and findout what is wrong?

Below you can see my code:

Class CaseService:

public class CaseService 
{
    public static void closeCases(Set<ID> cases, String closeReason)
    {
        System.debug('SKA - ' + cases);
        System.debug('SKA - ' + closeReason);
        List<Case> caseToUpdate = new List<Case>();
        for (Id caseId : cases)
        {
            Case c = new Case(Id = caseId);
            c.Reason = closeReason;
            c.Status = 'Closed'; 
            
            caseToUpdate.add(c);
        }
     
        update caseToUpdate;
        
    }
}

Class CaseCloseResource:

@RestResource(urlMapping='/case/*/close')
global class CaseCloseResource 
{
    @httpPost
    global static void closeCase(String closeReason)
    {
        System.debug('SKA - HTTPPOST - ' + closeReason + ' - ' + RestContext.request.requestURI);
         // Parse context
        RestRequest req = RestContext.request;
        String[] uriParts = req.requestURI.split('/');
        Id caseId = uriParts[2];
        // Call the service
        CaseService.closeCases(new Set<ID> { caseId }, closeReason);  
        
    }
}