function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
nagarjuna bnagarjuna b 

Clicking button it should reload the page, the callout must be perform asynchronous

My question is that clicking button it should reload the page, The callout must be perform asynchronous.

Now its works like a 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 update field on record based on  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;
        }
        
    }

Thanks
Anupam RastogiAnupam Rastogi
Hi Nagarjuna,

The question is not very clear. Can you please elaborate?

Thanks
nagarjuna bnagarjuna b
Hi Anupam,

There is button on Record Detail page , When user click this button , it should reload the page and callout should be perform backend.

Now its was working when user clicks this button ,  the page reloads after finishing the callout  , the callout takes 20 seconds until  callout finish user can not do any operation on detail page record.

I need to perform callout asynchronously at the time of clicking button without taking any time(immediately).

Thanks
Anupam RastogiAnupam Rastogi
Hi Nagarjuna,

The @future annotation is used for calling methods asynchronously, but the documentation states that it depends on the available system resources. So I guess as the overall  system load in the Org where you are working is less therefore the call is being made immediately.

Therefore I suggest that you go with the option of using VF (https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_continuation_overview.htm).

Thanks
nagarjuna bnagarjuna b
Hi Anupam,

Thanks for quick reply ,My client requirement is to use button without using visualforce page, Is there any workaround.

Thanks


 
Anupam RastogiAnupam Rastogi
Hi Nagarjuna,

Give this a try as a workaround if you do not wish to use VF. Instead of directly calling the apex method as it is not calling the web service async, you do the following and see if this works.

1. Create a new custom field on the calling object.
2. Change the JS you have written on the custom button 'onclick' to AJAX toolkit's sforce.connection.[update]. Use this update to modify the newly created field (per step 1 above).
3. Create a trigger that is based on this new field update, and call the class that you have created having the web service from this trigger.

So basically the flow should be like - 
 - The user clicks the button.
 - The JS executes and update the new field. (This field is not visible on the UI.)
 - The trigger executes that is checking this new field 'after update'.
 - The web service method is invoked from the trigger which is having @future(callout=true) annotation.

The workaround should not take much time. See if changing the way to calling this method makes the call behave asyncronously or not.

Thanks
Anupam
nagarjuna bnagarjuna b
Hi Anupam,

 Thank you for giving another solution, Its working fine. I will discuss with my client about this solution.

Thanks

 

 
Anupam RastogiAnupam Rastogi
Great...

If you found the options useful then please remember to mark it best for others to benefit from them... Thanks