Thursday, January 25, 2018

Calling External API from Salesforce


Before writting long stories I would like to define the scope of the article and it's target audience. The last article was an overview of Integration using the two protocols and in this article I am gonna focus on an simple example how to create http callouts in Apex

The recipe requires
1. End point URL
2. Add the end poit URL in the remote site settings
3. Write an HTTP callout class
The end point URL iam gonna use here is Yahoo weather API one word condition for a city. In this case, I take Account's billing city and display the current contion of the billing city in a Inline visualforce page.

The Inline visualfoce page loads and send the record id to the controller , The controller selects the record and send the city information from the Account billing address to the Endpoint helper class fetch weather.

ont forget to add remote site settings in your org to make this work.

The code is below


Apex Class
public class fetchweather{
            
            public string result = '';
          
            
    public fetchweather(string city) {
  
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        string endpoint  = 'https://query.yahooapis.com/v1/public/yql?q=';
        String encodedURL = EncodingUtil.urlEncode('select item.condition.text from weather.forecast where woeid in (select woeid from geo.places(1) where text="'+city+'")', 'UTF-8');
        string endpointurl = endpoint  + encodedURL + '&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys' ;
        System.debug(endpointurl+'++++');
        request.setEndpoint(endpointurl );
        request.setMethod('GET');
        HttpResponse response = http.send(request);
        System.debug(response.getBody());
        JSONParser parser = JSON.createParser(response.getBody());
        Map<String, Object> results = (Map<String, Object>)JSON.deserializeUntyped(response.getbody());
          system.debug('results ::'+ results );
          List<Object> lstforecast = (List<Object>)results.get('forecast');
           system.debug('lstforecast ::'+ lstforecast );
       while (parser.nextToken() != null) {
        if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) && (parser.getText() == 'text') ){
         parser.nextToken();
         result += 'The weather condition for '+ city+' is ' + parser.getText();
       }
       
       }
         //result = response.getbody();
     // return null; 
    }
}

VusualForce
==========
<apex:page standardController="Account" extensions="searchAccounts" showHeader="false" sidebar="false" >
<apex:form >
 <apex:pageBlock >
 <apex:pageBlockSection columns="1" >
 </apex:pageBlockSection>
 </apex:pageBlock> 
<span id="theText" style="font-style:italic">{!result} </span>
</apex:form>
</apex:page>

Extension
==========

global class searchAccounts {
    //Defining a standard controller
     public ApexPages.StandardController controller {get; set;}
     global string result {get;set;}
     public Account a;
    
    
    //Defining a standard controller
public searchAccounts(ApexPages.StandardController controller) {
this.controller = controller;
this.a = (Account)controller.getRecord();
system.debug('aaaaa'+a);
account acc = [select id,Account.BillingCity from account where id =:a.id];
fetchweather fw = new fetchweather(acc.BillingCity );
result = fw.result;
    }
       ///////
      
   
   
}

How to disable a row when Input checkbox is unchecked?

usually in Visualforce if we use Input check box when can re-render the page using ajax calls but the challenge occurs if we use the repeat tags with input field (Checkbox) Component

Here is a simple java script code which will do the job.

<script>  
function confirmDisbaled(ifchecked, id1 ,id2)
    {   
        //alert("Unchecking will reset the values to Zero.");
        document.getElementById(id1).disabled = !ifchecked;    
        document.getElementById(id2).disabled = !ifchecked; 
        document.getElementById(id1).value = 0; 
        document.getElementById(id2).value = 0; 
             
    } 
</script>


and the Visualforce page should be something like this



<apex:commandButton value="Select Products" action="{!editAll}"   rendered="{!isEdit == false}"/>
            <apex:outputPanel rendered="{!isEdit}">
                <apex:commandLink action="{!saveProducts}" styleClass="btn" style="text-decoration:none;padding:4px;" value="Save Products" target="_top"/>
                
                <apex:commandLink action="{!Cancel}" value="Cancel" target="_top" styleClass="btn" style="text-decoration:none;padding:4px;" />
                
                <apex:pageBlockTable value="{!selProdList}" var="opp" id="opp_table" styleclass="slds-table slds-table_bordered slds-table_cell-buffer">
                    <apex:column headerValue="Selected?" styleclass="slds-text-title_caps">
                        <apex:inputField value="{!opp.IsSelected__c}" styleclass="slds-truncate" onchange="return confirmDisbaled(this.checked, '{!$Component.ecl}','{!$Component.emt}');"/>    
                    </apex:column>
                    <apex:column value="{!opp.Product_Name__c}"/>           
                    <apex:column headerValue="Credit Limit (M)" styleclass="slds-text-title_caps">
                        <apex:inputField value="{!opp.Expected_Credit_Limit__c}" styleclass="slds-truncate" id="ecl"  onkeydown="limitfieldvalue('{!$Component.ecl}',13);" onkeyup="limitfieldvalue('{!$Component.ecl}',13);"/>
                    </apex:column>
                    <apex:column headerValue="Max Tenure (Mn)" styleclass="slds-text-title_caps">
                        <apex:inputField value="{!opp.Expected_Max_Tenure__c}" id="emt" onkeydown="limitfieldvalue2('{!$Component.emt}',3);" onkeyup="limitfieldvalue2('{!$Component.emt}',3);"/>
                    </apex:column>
                </apex:pageBlockTable> 
            </apex:outputPanel>


The confirmedisabled() method is set with Inputs in the Check box field component and Id of the repective field which should be disable on clicking checkbox is passed as the input along with IfChecked Value. Changing !(Not) in the java script method will render the inverted outputs.