0

I am using Rest resources to query tooling api objects. My code is as follows:

public HttpRequest getObjectDescription() {
    String name = localName.replace('__c', '');  //localName is a class variable

    HttpRequest request = new HttpRequest();
    HttpResponse response = new HttpResponse();

    request.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
    request.setHeader('Content-Type', 'application/json');
    String domainurl = URL.getSalesforceBaseUrl().toExternalForm();

    request.setEndpoint(domainurl+'/services/data/v35.0/tooling/query/?q=Select+DeveloperName,Description+from+CustomObject+where+DeveloperName=\'' + name + '\'');
    request.setMethod('GET');

    return request;
}

 public String getDescriptionInfo() {
    Http h = new Http();

    HttpRequest request = getObjectDescription();

    HttpResponse response = h.send(request);
    JSONParser parser = JSON.createParser(response_body);

    // parsing the response here and returning the result
 }

VF Code:

<apex:pageBlock title="Project" rendered="{!ISNULL(localName)}">
            <apex:pageBlockSection >
                How to use<br/>
                FAQs<br/>
                Explore documentation<br/>
                <apex:outputLink value="/apex/DisplayObjectFields?localName=tech_asset__c">Example Object
                </apex:outputLink>
            </apex:pageBlockSection>
        </apex:pageBlock>
        <apex:pageBlock title="{!label}" rendered="{!NOT(ISNULL(localName))}">
           <apex:pageBlockSection > {!DescriptionInfo} </apex:pageBlockSection> 
            <apex:pageBlockSection > LocalName: {!localName} </apex:pageBlockSection>
            <apex:pageBlockSection > CRUD Access: {!CRUDAccess} </apex:pageBlockSection>

        </apex:pageBlock>

I have looked up this issue and it appears that you cannot perform a DML after a callout. I am not inserting or updating anything, I am just querying. However I still get this error from time to time. I am not able to use @future(callout=true) either because I need to return the String result after parsing the response, and to use @future it needs to be static and void. Is there a way to fix this?

  • Actually, it's about performing DML before a callout. Are you performing any of it before you call getDescriptionInfo? – Sebastian Kessel Jul 17 '17 at 21:18
  • 1
    You might be surprised what counts as DML. You only get the error intermittently? Do you have any conditional logic? – Adrian Larson Jul 17 '17 at 21:19
  • @SebastianKessel in my visualforce page I just call getDescriptionInfo(), which calls getDescription() first. getDescription() performs the DML and then I make a callout in getDescriptionInfo(). – mvss1995 Jul 17 '17 at 21:23
  • @AdrianLarson yes I get the error randomly, but not too often. I have conditional logic when I parse the response later in getDescriptionInfo(), but other than that no. – mvss1995 Jul 17 '17 at 21:25
  • 1
    Interesting. I never tried to hit a callout in a getter like that. There could be other DML in the init of that page that is causing the callout to fail. I recommend moving some of your callout code into a different method (one called from an action tag in your VF, for example) and then populate a property that will be displayed where DescriptionInfo is displayed now. – Sebastian Kessel Jul 17 '17 at 21:53
2

I can't see the entirety of your code but I suspect that I know the reason. When adding the callout in the getter like you're doing, it gets processed along with all the other initialization processes for the VF page (and then re-processed if you re-render that part of the page).

I recommend you move your callout into its own method, and then populate a property on your return. That method could be called in the action method for the VF page, for example.

Then, In your VF page, instead of calling for the current function, simply display the property populated in the step before.

  • Somewhat related: salesforce.stackexchange.com/q/158938/2995 – Adrian Larson Jul 17 '17 at 22:04
  • So is it because of the getObjectDescription() call that is happening inside getDescriptionInfo()? – mvss1995 Jul 17 '17 at 23:22
  • It's likely because you have DML somewhere in the page initialization that is happening before the call out. Just put the callout in the right order and abstract it from the actual property. – Sebastian Kessel Jul 18 '17 at 0:10
  • If this helped you, please mark the solution as accepted so others can benefit – Sebastian Kessel Jul 18 '17 at 22:36

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.