2

My question is, should clicking a button reload a page and perform an asynchronous callout?

It looks like its reloading the page after finishing the callout.

Custom Button : Execute JavaScript

{!REQUIRESCRIPT("/soap/ajax/15.0/connection.js")} 
{!REQUIRESCRIPT("/soap/ajax/15.0/apex.js")} 
location.reload();
sforce.apex.execute("MyQuote","callNetsuite",{lstQuoteID:"{!Quote.Id}"}); 

Apex class calls external application and updates the record field based on the response

global class MyQuote
{

    @future(callout=true)
    webservice static void callNetsuite(String lstQuoteID) 
    { 
       List<Quotes> requestQuote = new list<Quotes>();
       map<Id,Quote> mapquote = new map<Id,Quote>();
       list<Quote> lstQuote = [select Id,Name,Quote.Account.Name,Quote.Account.Netsuite_Customer_Id__c,
                                      (select Id,Quantity,UnitPrice,Product2Id,Product2.Name,Product2.Netsuite_Product_Id__c from QuoteLineItems) 
                                       from Quote where Id=:lstQuoteID];


       HttpRequest req = new HttpRequest();
       HttpResponse res = new HttpResponse();
       Http http = new Http();
       String responseBody;
       String jsonbody = '[{"trandate":"4/1/2015","terms":"","shipaddresslist":"","recordtype":"salesorder","otherrefnum":"test quote SO1","item":                       [{"quantity":3.00,"item":"128","internalid":"","amount":399.00},{"quantity":3.00,"item":"130","internalid":"","amount":89.99}],"internalid":"","externalid":"0Q028000000L39DCAS","entity":"1249","billaddresslist":""}]'

       String authorizationHeader = 'NLAuth nlauth_account=XXXXX,nlauth_email=XXXXX,nlauth_signature=XXXXX';
       String endpoint = 'https://rest.na1.netsuite.com/app/site/hosting/restlet.nl?script=598&deploy=1';

       req.setHeader('Authorization', authorizationHeader);
       req.setHeader('Content-Type','application/json');
       req.setMethod('POST');
       req.setTimeOut(120000) ; 
       req.setEndpoint(endpoint);
       req.setBody(jsonbody);


       if (!Test.isRunningTest())
       {
           try 
           {
               //Send endpoint to Netsuite
               res = http.send(req);
               responseBody = res.getBody();
               System.debug('responseBody:'+responseBody);
               System.debug('BodyResponse:'+res.toString());
           } catch(System.CalloutException e) {
             System.debug(res.toString());
           }
      }else {
        // dummy data
        responseBody = '200';
       }


       if(responseBody != null && responseBody != '')
       {
            List<resQuotes> quotelst = (List<resQuotes>)JSON.deserialize(responseBody,List<resQuotes>.class);
            list<Quote> updateQuotelst = new list<Quote>();
            system.debug('quotelst:'+quotelst);
            for(resQuotes resp : quotelst)
              {

                 updating the quote record based on response 

              }



       }

   }    

   global class resQuotes
   {
     webService String recordtype;
     webService String internalid;
     webService String externalid;
     webService List<resItem> item;
     webService String salesordernumber;
     webService String issuccess;
     webService String errorcode;
     webService String errormessage;
   }

   global class resItem 
   {
     webService String internalid;
     webService String externalid;
     webService String status;
    }

}

4 Answers 4

0

You should look into Queueable Apex and Queueable Interface instead of using a future call, this would mean the page would instantly reload and the APEX would fire off asynchronously.

0

Can you try this?

{!REQUIRESCRIPT("/soap/ajax/15.0/connection.js")}
    {!REQUIRESCRIPT("/soap/ajax/15.0/apex.js")}

    setTimeout(function(){
        sforce.apex.execute("MyQuote","callNetsuite",{lstQuoteID:"{!Quote.Id}"});
    },333);
    setTimeout(function(){
        location.reload();
    },334);
0

There is no need to use future method in your webservice class. I have tried with similar code in my org and callout is performed successfully after reloading the window. However, What you know can do is to catch the response and show a popup based on response so that user will know the status of callout and then reload the window, if necessary. The callout should take not a lot of time or else there will be read time-out error.

-1

The callout will be asynchronous if you use future annotation like below.

Also, sforce.connection has onSuccess and onFailure parameter and runs in asynchronous mode.

Button:

var queryResult = sforce.connection.execute("ClassName","MethodName", MethodParam:"recid",{ 
onSuccess : success, 
onFailure : failure 
}); 

function success(result){ 
var ParentDocId = result.getArray("records");
location.reload();
} 

function failure(error) { 
alert("An error has occurred " + error); 
}

Class:

webservice static void method1(){
method2();
}

@future(callout=true)
public static void method2(){}
1
  • Your answer its correct. but you can do the same without change the class
    – Torsen
    Mar 14, 2017 at 8:13

You must log in to answer this question.

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