2

Want to update a VisualForce Page once my @future Apex Callout is done. How can I update a VisualForcePage, once the Webservice callout is done? Could I somehow divide the SearchCRM method, so that it would deliver a String (XML) as response, which i then could handle in a nother method. And once that other method finished, update the VisualForce page, (for instance the cID input field)?

If this is not possible, do you have an idea of alternative solutions? I saw this (How to synchronize asynchronous Apex ) but seems liek a bad solution with an object update and then a trigger on that? Any thoughts?

Below is my VF page, which calls the Search method from the extension, once it is visited:

<apex:page standardController="Contact" extensions="contactSTDCExtension" action="{!search}">
<h1>Header</h1>
This is your Page
<apex:form>
<apex:inputtext id="cID"/>
<apex:relatedList list="Cases"/>
</apex:form>
</apex:page>

Below is extension:

public with sharing class contactSTDCExtension 
{
public contactSTDCExtension(ApexPages.StandardController controller) 
{

}
public void search()
{
    It.searchCRM('example@example.com','');
}
}

Below is my webservice callout:

global class it
{
    global class CRMContact 
    {
        public String changed {get; set;}
        public String contactId {get; set;}
        public String customerNumber {get; set;}
        public String email {get; set;}
        public String firstName  {get; set;}
        public String lastName {get; set;}
    } 
    @future (callout=true)
    public static void searchCRM(String email, String phoneNumber) 
    {
        Boolean requestFromPhone = string.isBlank(email);//isBlank(email); // if not
        // Create a JSON generator object
        JSONGenerator gen = JSON.createGenerator(true);
        // open the JSON generator
        //gen.writeStartArray();
        gen.writeStartObject();
        if (requestFromPhone)
        {
            gen.writeStringField('PhoneNumber', phoneNumber);
        }
        else
        {
            gen.writeStringField('Email', email);
        }
        gen.writeEndObject();    
        // close the JSON generator
        // gen.writeEndArray();
        // create a string from the JSON generator
        String jsonContactRequestString = gen.getAsString();
        // create an HTTPrequest object    
        HttpRequest req = new HttpRequest();
        // set up the HTTP request with a method, endpoint, header, and body
        req.setMethod('POST');
        req.setEndpoint('XXXXXXXXXXXXXX');
        req.setHeader('Content-Type', 'application/json');
        req.setTimeout(5000);
        String username = 'XXXXXXXXXX';
        String password = 'XXXXXXXXXXXXXX';
        Blob headerValue = Blob.valueOf(username + ':' + password);
        String authorizationHeader = 'BASIC ' + EncodingUtil.base64Encode(headerValue);
        req.setHeader('Authorization', authorizationHeader);     
        req.setBody(jsonContactRequestString);    
        // create a new HTTP object
        Http http = new Http();
        // create a new HTTP response for receiving the remote response
        // then use it to send the configured HTTPrequest
        HTTPResponse res = http.send(req);
        // debugging call, which you can check in debug logs
        // Examine the status code from the HTTPResponse
        // If status code != 200, write debugging information, done
        if (res.getStatusCode() == 200)
        {
            ct = new Contact(); //Initialize new contact with response from webservice

        }
        else //Response code is other than 200.
        {
            System.debug('Error from ' + req.getEndpoint() + ' : ' +
            res.getStatusCode() + ' ' + res.getStatus());
        }        
    }
}
  • 3
    Take a look at How to perform equivalent of an AJAX long-poll with Visualforce and particularly Getting Started with the Force.com Streaming API. But bear in mind that while an @future typically runs quite quickly, quick execution is not guaranteed by the platform. – Keith C Jun 3 '15 at 10:51
  • Does the callout need to be an @future method? VF can execute the callout synchronously so I would restructure the class to have both a sync and async method and call the sync method during the VF code execution then you can update the page after the callout. This assume the callout can be made synchronously – Eric Jun 3 '15 at 16:41
  • @Eric - Can you elaborate on the sync part. How would I be able to do Sync callouts from VF-page? It's a callout to an external Webserver, which returns something which i need to show on the VF page. – Claus Machholdt Jun 3 '15 at 16:56
  • @ClausMachholdt - You do not need an future method to make a callout from a VF page. You can capture the response and return it to the VF page method and parse it in real time. You will have to show them a waiting icon or something while it is making the callout. Just use your same methods but structure it so you have ability to call it sync and async. – Eric Jun 3 '15 at 21:09
  • @Eric - It sounds very interesting. Do you know where to find information on how to do it? And can I utilize the current Apex Class to do the callout? I have quite some logic, which I need to do with the response from the webserver. Logic which is not listed in code above. But it involves XML parsing to a Salesforce object and afterwards search for a match in Salesforce and upsert the object. And after that, I want to show the updated/inserted contact. – Claus Machholdt Jun 4 '15 at 8:04
3

Change you signatures to this:

@future (callout=true)
public static void searchCRMAsync(String email, String phoneNumber){
    searchCRM(email,phoneNumber);
}

public static Dom.Document searchCRM(String email, String phoneNumber) {//Code here}

You will have to update your trigger to call searchCRMAsync and you will have to update your method to return what you want or the Dom.Document like I made it...

Call the searchCRM from you VF page and parse the returned response as needed

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.