https://www.salesforcebolt.com/2023/07/weather-apis-integration-named.html
LWC Integration with Weather API:
Named Credentials:
To simplify the setup of authenticated callouts, specify a named credential as the callout endpoint. Create an external credential to specify an authentication protocol and permission set or profile to use when authenticating to an external system.
We will be using WeatherAPI.com for this integration. I have created a free account over to get the API key.
Now first step here would be to create an External Credentials in Salesforce.
To create an External Credentials you can simply go to Setup --> Named Credentials and click on External Credentials tab:
Create a principal for it and add your API key as a parameter
Create a new custom header as shown below with the same API key parameter. By creating a custom header here you don't have to create it again in your named credentials.
Create a new custom header as shown below with the same API key parameter. By creating a custom header here you don't have to create it again in your named credentials.
Now as you have created an External Credentials, let's create Named Credentials.
After you create principals and external credentials, take these steps to give permission sets and profiles access to the principals of the external credential.
WeatherAPI.cls
==============
public with sharing class WeatherAPI {
@AuraEnabled
public static string getWeather(String city){
Http http = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:WeatherAPI/current.json?q='+city);
req.setMethod('GET');
HttpResponse res = http.send(req);
return res.getBody();
}
}
WeatherAPI.html
=================
<template>
<lightning-card title="Weather APIs">
<div class="slds-var-m-around_medium">
<lightning-input onchange={handleonchange} label="Search City">
</lightning-input>
<br/>
<lightning-button label="Get Weather" onclick={buttonClick}>
</lightning-button>
<br/>
<img src={imageURL} />
<b>{condition}</b>
</div>
</lightning-card>
</template>
WeatherAPI.js
==============
import { LightningElement } from 'lwc';
import getWeather from '@salesforce/apex/WeatherAPI.getWeather';
export default class WeatherAPI extends LightningElement {
city;
condition;
imageURL;
handleonchange(event) {
this.city = event.target.value;
}
buttonClick() {
getWeather({ city: this.city }).then((response) => {
console.log("###Response : " + response);
let parsedData = JSON.parse(response);
this.imageURL = parsedData.current.condition.icon;
this.condition = parsedData.current.condition.text;
})
.catch((error) => {
this.condition = 'No matching location found.';
console.log('###Error : ' + JSON.stringify(error));
});
}
}
==============
public with sharing class WeatherAPI {
@AuraEnabled
public static string getWeather(String city){
Http http = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:WeatherAPI/current.json?q='+city);
req.setMethod('GET');
HttpResponse res = http.send(req);
return res.getBody();
}
}
WeatherAPI.html
=================
<template>
<lightning-card title="Weather APIs">
<div class="slds-var-m-around_medium">
<lightning-input onchange={handleonchange} label="Search City">
</lightning-input>
<br/>
<lightning-button label="Get Weather" onclick={buttonClick}>
</lightning-button>
<br/>
<img src={imageURL} />
<b>{condition}</b>
</div>
</lightning-card>
</template>
WeatherAPI.js
==============
import { LightningElement } from 'lwc';
import getWeather from '@salesforce/apex/WeatherAPI.getWeather';
export default class WeatherAPI extends LightningElement {
city;
condition;
imageURL;
handleonchange(event) {
this.city = event.target.value;
}
buttonClick() {
getWeather({ city: this.city }).then((response) => {
console.log("###Response : " + response);
let parsedData = JSON.parse(response);
this.imageURL = parsedData.current.condition.icon;
this.condition = parsedData.current.condition.text;
})
.catch((error) => {
this.condition = 'No matching location found.';
console.log('###Error : ' + JSON.stringify(error));
});
}
}
Before using Fetch API in the LWC, we need to set up the CSP Trusted Site definition for remote sites. Before making a callout from Apex we need to set up remote site settings, and in LWC we need to set up CSP trusted sites.
getMyIp.html
<template>
<lightning-card>
<h3 slot="title">
<lightning-icon icon-name="utility:connected_apps" size="small"></lightning-icon>
My IP
</h3>
<div slot="footer">
</div>
<div class="slds-p-around_medium lgc-bg">
<lightning-button label="Get My IP" onclick={getIP}></lightning-button>
</div>
<div class="slds-p-around_medium lgc-bg">
<lightning-textarea readonly value={myIp} rows="7" style="height:150px;"></lightning-textarea>
</div>
</lightning-card>
</template>
getMyIp.js
import { LightningElement, track } from 'lwc';
export default class GetMyIp extends LightningElement {
@track myIp;
getIP() {
const calloutURI = 'https://api.ipify.org?format=json';
fetch(calloutURI, {
method: "GET"
}).then((response) => response.json())
.then(repos => {
console.log(repos)
this.myIp = repos.ip;
console.log(this.myIp);
});
}
}
==================================================
Source code for Salesfoce and Indian Postal Pin system
===========Apex class PostalDepartmentAPI=================
public class PostalDepartmentAPI {
@AuraEnabled
public static list<PostalResponseWrapper> postOfficeByPincode(string pincode){
list<PostalResponseWrapper> postalList = new list<PostalResponseWrapper>();
//list out endpoint
string endpoint = 'https://api.postalpincode.in/pincode/';
if(string.isNotBlank(pincode)){
endpoint = endpoint+ pincode; //https://api.postalpincode.in/pincode/754205
}
//instantiate http
Http h = new Http();
//create Request for your http api call
HttpRequest hreq = new HttpRequest();
hreq.setMethod('GET');
hreq.setEndpoint(endpoint);
hreq.setHeader('content-type','application/json');
//invoke rest call with send()
HttpResponse hresp = h.send(hreq);
system.debug('****hresp'+hresp.getStatusCode());
//if response sucess then only parase
if(hresp.getStatusCode() ==200){
JSONParser parser = JSON.createParser(hresp.getBody());
parser.nextToken();
while(parser.nextToken()!=NULL){
if(parser.getcurrentToken() == JSONTOKEN.START_ARRAY){
while(parser.nextToken()!=NULL){
if(parser.getcurrentToken() == JSONTOKEN.START_OBJECT) {
PostalResponseWrapper eachPostal = (PostalResponseWrapper)parser.readValueAs(PostalResponseWrapper.class);
eachPostal.PINCode = pincode;
postalList.add(eachPostal);
system.debug('eachPostal'+eachPostal);
}
}
/**/
}
}
}
system.debug('postalList'+postalList);
return postalList;
}
@AuraEnabled
public static list<PostalResponseWrapper> postOfficeByBranchName(string branchName){
list<PostalResponseWrapper> postalList = new list<PostalResponseWrapper>();
//list out endpoint
string endpoint = 'https://api.postalpincode.in/postoffice/';
if(string.isNotBlank(branchName)){
endpoint = endpoint+ branchName; //https://api.postalpincode.in/postoffice/Gachibowli
}
//instantiate http
Http h = new Http();
//create Request for your http api call
HttpRequest hreq = new HttpRequest();
hreq.setMethod('GET');
hreq.setEndpoint(endpoint);
hreq.setHeader('content-type','application/json');
//invoke rest call with send()
HttpResponse hresp = h.send(hreq);
system.debug('****hresp'+hresp.getStatusCode());
//if response sucess then only parase
if(hresp.getStatusCode() ==200){
JSONParser parser = JSON.createParser(hresp.getBody());
parser.nextToken();
while(parser.nextToken()!=NULL){
if(parser.getcurrentToken() == JSONTOKEN.START_ARRAY){
while(parser.nextToken()!=NULL){
if(parser.getcurrentToken() == JSONTOKEN.START_OBJECT) {
PostalResponseWrapper eachPostal = (PostalResponseWrapper)parser.readValueAs(PostalResponseWrapper.class);
postalList.add(eachPostal);
system.debug('eachPostal'+eachPostal);
}
}
}
}
}
system.debug('postalList'+postalList);
return postalList;
}
public class PostalResponseWrapper{
@AuraEnabled
public string Name;
@AuraEnabled
public string Description;
@AuraEnabled
public string PINCode;
@AuraEnabled
public string BranchType;
@AuraEnabled
public string DeliveryStatus;
@AuraEnabled
public string Circle;
@AuraEnabled
public string District;
@AuraEnabled
public string Division;
@AuraEnabled
public string Region;
@AuraEnabled
public string State;
@AuraEnabled
public string Country;
}
}
===================Component===========
<aura:component controller="PostalDepartmentAPI" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
<aura:attribute name="indiapostlist" type="list"></aura:attribute>
<aura:attribute name="searchPin" type="string"></aura:attribute>
<aura:attribute name="searchBranch" type="string"></aura:attribute>
<aura:attribute name="postalColumns" type="list"></aura:attribute>
<div class="slds-box" style="color:blue">
<lightning:input name="postalpin" value="{!v.searchPin}"
label="Please Enter PIN Code to search post office details"
max="999999"></lightning:input>
<lightning:input name="postalBranch" value="{!v.searchBranch}"
label="Please Enter Post office branch to search post office details"
></lightning:input>
<lightning:button variant="success" label="Get Postal Details" title="Get Postal Details" onclick="{! c.invokePostalAPI }"/>
</div>
<div class="slds-box">
<lightning:datatable
keyField="id"
data="{! v.indiapostlist }"
columns="{! v.postalColumns }"
hideCheckboxColumn="true"/>
</div>
</aura:component>
=========Component Controller ================
({
invokePostalAPI : function(component, event, helper) {
component.set('v.postalColumns',[
{label:'Name',fieldName:'Name',type:'text'},
{label:'Description',fieldName:'Description',type:'text'},
{label:'PINCode',fieldName:'PINCode',type:'text'},
{label:'BranchType',fieldName:'BranchType',type:'text'},
{label:'DeliveryStatus',fieldName:'DeliveryStatus',type:'text'},
{label:'Circle',fieldName:'Circle',type:'text'},
{label:'District',fieldName:'District',type:'text'},
{label:'Division',fieldName:'Division',type:'text'},
{label:'Region',fieldName:'Region',type:'text'},
{label:'State',fieldName:'State',type:'text'},
{label:'Country',fieldName:'Country',type:'text'}
]);
var action;
var pincode = component.get('v.searchPin');
var branchName = component.get('v.searchBranch');
if(pincode){
action = component.get("c.postOfficeByPincode");
action.setParams({
"pincode":pincode
});
}
else if(branchName){
action = component.get("c.postOfficeByBranchName");
action.setParams({
"branchName":branchName
});
}
action.setCallback(this,function(response){
var state = response.getState();
if(state === "SUCCESS"){
component.set("v.indiapostlist",response.getReturnValue());
}
});
$A.enqueueAction(action);
}
})
<aura:application extends="force:slds">
<c:PostalDepartmentAPI />
</aura:application>
========================================
Custom Table In LWC (salesforcelog.com)
public class PostalDepartmentAPILWC {
@AuraEnabled
public static list<PostalResponseWrapper> postOfficeByPincode(string pincode){
list<PostalResponseWrapper> postalList = new list<PostalResponseWrapper>();
//list out endpoint
string endpoint = 'https://api.postalpincode.in/pincode/';
if(string.isNotBlank(pincode)){
endpoint = endpoint+ pincode; //https://api.postalpincode.in/pincode/754205
}
//instantiate http
Http h = new Http();
//create Request for your http api call
HttpRequest hreq = new HttpRequest();
hreq.setMethod('GET');
hreq.setEndpoint(endpoint);
hreq.setHeader('content-type','application/json');
//invoke rest call with send()
HttpResponse hresp = h.send(hreq);
system.debug('****hresp'+hresp.getStatusCode());
//if response sucess then only parase
if(hresp.getStatusCode() ==200){
JSONParser parser = JSON.createParser(hresp.getBody());
parser.nextToken();
while(parser.nextToken()!=NULL){
if(parser.getcurrentToken() == JSONTOKEN.START_ARRAY){
while(parser.nextToken()!=NULL){
if(parser.getcurrentToken() == JSONTOKEN.START_OBJECT) {
PostalResponseWrapper eachPostal = (PostalResponseWrapper)parser.readValueAs(PostalResponseWrapper.class);
eachPostal.PINCode = pincode;
postalList.add(eachPostal);
system.debug('eachPostal'+eachPostal);
}
}
/**/
}
}
}
system.debug('postalList'+postalList);
return postalList;
}
public class PostalResponseWrapper{
@AuraEnabled
public string Name;
@AuraEnabled
public string Description;
@AuraEnabled
public string PINCode;
@AuraEnabled
public string BranchType;
@AuraEnabled
public string DeliveryStatus;
@AuraEnabled
public string Circle;
@AuraEnabled
public string District;
@AuraEnabled
public string Division;
@AuraEnabled
public string Region;
@AuraEnabled
public string State;
@AuraEnabled
public string Country;
}
}
<template><!-- Header Part --><lightning-card title="Postal APIs"><div class="slds-var-m-around_medium"><lightning-input onchange={handleonchange} label="Pin Code"></lightning-input><br/><lightning-button label="Get Postal Address" onclick={buttonClick}></lightning-button><br/></div></lightning-card><lightning-card title="Result"><!-- Table start--><table class="slds-table slds-table_cell-buffer slds-table_bordered"><!--Column Header start--><thead><tr class="slds-line-height_reset"><th class="" scope="col"><div class="slds-truncate" title="Name">Name</div></th><th class="" scope="col"><div class="slds-truncate" title="Pin Code ">Pin Code</div></th></tr></thead><tbody><!--data is an array of record which is set in .js file--><template for:each={parsedData} for:item="res"><tr key={res.Id}><th scope="col"><div>{res.Name}</div></th><th scope="col"><div>{res.PINCode}</div></th></tr></template></tbody></table></lightning-card></template>import { LightningElement, wire, api } from 'lwc';import postOfficeByPincode from '@salesforce/apex/PostalDepartmentAPI.postOfficeByPincode';export default class PostalDepartmentApiLWC extends LightningElement {pincode;Name;PincodeValue;parsedData;handleonchange(event){this.pincode = event.target.value;console.log(event.target.value);}buttonClick(){// alert('Response ');postOfficeByPincode({pincode: this.pincode}).then((response) => {this.parsedData = response;})}}<?xml version="1.0" encoding="UTF-8"?><LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata"><apiVersion>58.0</apiVersion><isExposed>true</isExposed><targets><target>lightning__Tab</target></targets></LightningComponentBundle>LWC Callout to get External data:
public class LwcCalloutMock { @AuraEnabled public static list<AccountsWrapper> getAccountDetails(){ list<AccountsWrapper> postalList = new list<AccountsWrapper>(); Http http = new Http(); HttpRequest req = new HttpRequest(); req.setEndpoint('https://mocki.io/v1/0cf842e2-8624-49a4-8b44-f540552f1efb'); req.setMethod('GET'); HttpResponse hresp = http.send(req); System.debug('Response ### '+hresp.getBody()); if(hresp.getStatusCode() ==200){ JSONParser parser = JSON.createParser(hresp.getBody()); parser.nextToken(); while(parser.nextToken()!=NULL){ if(parser.getcurrentToken() == JSONTOKEN.START_OBJECT) { system.debug('start object '); AccountsWrapper eachAccount = (AccountsWrapper)parser.readValueAs(AccountsWrapper.class); system.debug('eachAccount'+eachAccount); postalList.add(eachAccount); } } } system.debug('postalList'+postalList); return postalList; } public class AccountsWrapper { @AuraEnabled public string Name; @AuraEnabled public string Description; } } <template> <lightning-card title="Callout"> <div class="slds-var-m-around_medium"> <lightning-button label="Get External Accounts" onclick={buttonClick}> </lightning-button> </div> </lightning-card> <lightning-card title="Result"> <!-- Table start--> <table class="slds-table slds-table_cell-buffer slds-table_bordered"> <!--Column Header start--> <thead> <tr class="slds-line-height_reset"> <th class="" scope="col"> <div class="slds-truncate" title="Name">Name</div> </th> <th class="" scope="col"> <div class="slds-truncate" title="Description">Description </div> </th> </tr> </thead> <tbody> <!--data is an array of record which is set in .js file--> <template for:each={parsedData} for:item="res"> <tr key={res.Id}> <th scope="col"> <div>{res.Name}</div> </th> <th scope="col"> <div>{res.Description}</div> </th> </tr> </template> </tbody> </table> </lightning-card> </template> import { LightningElement, wire } from 'lwc'; import getAccountDetails from '@salesforce/apex/LwcCalloutMock.getAccountDetails'; export default class LwcCalloutMock extends LightningElement { parsedData; buttonClick() { getAccountDetails() .then((response) => { console.log("###Response : " + response); this.parsedData = response; }) .catch((error) => { this.condition = 'No matching location found.'; console.log('###Error : ' + JSON.stringify(error)); }); } }
No comments:
Post a Comment