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.

  • can you clarify, is this triggered from VF page? – Narendra Nimmana Aug 28 '18 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. – salesforce Developer Aug 28 '18 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 Aug 28 '18 at 5:27
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.

  • 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 Aug 28 '18 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. – Sunil Aware Aug 28 '18 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;
}

}

  • 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 Aug 28 '18 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. – Narendra Nimmana Aug 28 '18 at 5:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.