1

I have a situation where I have to insert data into a wrapper class and a bunch of objects to save in Salesforce first and then make an API call. As we know, salesforce will not allow us to make any Callouts followed by DMLs. as a work around, I have written a separate class with @Future method and calling that from main class. That @Future method holds all http requests and callouts. But the main problem is that I am receiving error or success message from the response. I need to return that message to show ERROR or SUCCESS message in the lightning page. I am using the response message and getMessage in components and using it to show that info. @Future method will not return anything and also will not save data in global variables too.
Can anyone please help me with this situation. If there is anything else can be done without using @future method, Please let me know that too. Thank you, Ashok.

3
  • can you clarify, is this triggered from VF page? Commented Aug 28, 2018 at 5:14
  • If your Future method is executing from Trigger, then I don't think you will be able to show the message in Edit or Detail layout. but if you are using VF page then you can use Continuation. Commented Aug 28, 2018 at 5:26
  • No @NarendraNimmana . It is not for Trigger. There will be page where customer can choose the items to create an invoice. Then, it is making an API call and saving that invoice in JAVA application. What I need is to save the Invoice in Salesforce before making an API call. So, I took the selected items into a wrapper and inserted it in local first. Rest is the same story as above.
    – AshSFcloud
    Commented Aug 28, 2018 at 5:27

2 Answers 2

2
You can achieve this by three way

1. Use Queueable

ID jobID = System.enqueueJob(new AsyncExecutionExample());

which will return ID of job and by which you can query your job status once its completed you can show the result of callout.
  1. Separate transaction in two

    • Complete DML operations before callout and return cotroll on page and dont show any message.
    • Make callout use values from first transaction and you can show result on page.
  2. Use your normal approach as you mentioned above once control received back on page from transaction set timeout for 5-10ms and check status of future and show respective result to user.

2
  • I do not understand what you mean check STATUS OF FUTURE in the third step. Can be be more specific about that. First two steps are not useful to me as I am updating object.list with two new values from response.
    – AshSFcloud
    Commented Aug 28, 2018 at 7:50
  • In third step you can update Callout log somewhere like custom object and you can check status by queryng from that object. Commented Aug 28, 2018 at 7:57
0

I think it's better to use Continuous concept here, it is similar to the rest Callout only difference is it works asynchronously, so no need of using @future.
Asynchronous callouts (Continuous Callots) that are made from a Visualforce page don’t count toward the Apex limit of 10 synchronous requests that last longer than five seconds. As a result, you can make more long-running callouts and you can integrate your Visualforce pages with complex back-end assets. Follow this Make Long-Running Callouts from a Visualforce Page, it has explained everything clearly.

I have just copied the Code from the link mentioned above.
VF Page

<apex:page controller="ContinuationController" showChat="false" 
showHeader="false">
 <apex:form >
  <!-- Invokes the action method when the user clicks this button. -->
 <apex:commandButton action="{!startRequest}" 
          value="Start Request" reRender="result"/> 
</apex:form>

<!-- This output text component displays the callout response body. -->
<apex:outputText id="result" value="{!result}" />
</apex:page>

Controller:

public with sharing class ContinuationController {
// Unique label corresponding to the continuation
public String requestLabel;
// Result of callout
public String result {get;set;}
// Callout endpoint as a named credential URL 
// or, as shown here, as the long-running service URL
private static final String LONG_RUNNING_SERVICE_URL = 
    '<Insert your service URL>';

// Action method
public Object startRequest() {
  // Create continuation with a timeout
  Continuation con = new Continuation(40);
  // Set callback method
  con.continuationMethod='processResponse';

  // Create callout request
  HttpRequest req = new HttpRequest();
  req.setMethod('GET');
  req.setEndpoint(LONG_RUNNING_SERVICE_URL);

  // Add callout request to continuation
  this.requestLabel = con.addHttpRequest(req);

  // Return the continuation
  return con;  
}

// Callback method 
public Object processResponse() {   
  // Get the response by using the unique label
  HttpResponse response = Continuation.getResponse(this.requestLabel);
  // Set the result variable that is displayed on the Visualforce page
  this.result = response.getBody();

  // Return null to re-render the original Visualforce page
  return null;
}

}

2
  • My apologies @NarendraNimmana .. I should have mentioned that we are not using VF. Actually, it is Lightning. It seems above method is for Classic VF page. I really appreciate your quick response. Can we do the same in Lightning too??
    – AshSFcloud
    Commented Aug 28, 2018 at 5:46
  • I did it once in VF, but it's not useful for lightning. Currently i don't have any answer let me think of get back to you. Commented Aug 28, 2018 at 5:50

You must log in to answer this question.

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