This post explains how to make the callout in Lightning Web Components(lwc)
We can make the callout from Lightning Web Component in two ways
1. Client-side controller(JS controller)
2. Using the server-side controller(Apex Class)
In this demo, I am using https://www.alphavantage.co/
alpha vantage provides the following services for free
Example endpoint URL:
https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=USD&to_currency=INR&apikey=<API_KEY>
Sample JSON Response
HTTPCalloutInLWC.js
We can make the callout from Lightning Web Component in two ways
1. Client-side controller(JS controller)
2. Using the server-side controller(Apex Class)
In this demo, I am using https://www.alphavantage.co/
alpha vantage provides the following services for free
- Realtime and historical stock data
- FX(Foreign exchange) and cryptocurrency feeds
- 50+ technical indicators
- Global coverage
Get your free API Key https://www.alphavantage.co/support/#api-key
Endpoint URL : https://www.alphavantage.co
Endpoint URL : https://www.alphavantage.co
Make the Callout to Alpha Vantage and it sends the data in the form of JSON.
In this demo, I am making the callout to check the foreign currency exchange rates.Example endpoint URL:
https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=USD&to_currency=INR&apikey=<API_KEY>
Sample JSON Response
{
"Realtime Currency Exchange Rate": {
"1. From_Currency Code": "USD",
"2. From_Currency Name": "United States Dollar",
"3. To_Currency Code": "INR",
"4. To_Currency Name": "Indian Rupee",
"5. Exchange Rate": "70.87700000",
"6. Last Refreshed": "2019-08-09 14:01:57",
"7. Time Zone": "UTC",
"8. Bid Price": "70.86700000",
"9. Ask Price": "70.88700000"
}
}
Note
Make sure to white-list the endpoint URL based on your approach.
Make sure to white-list the endpoint URL based on your approach.
Client-side controller
Make sure your endpoint is white-list in Content Security Policies (CSP)
Path:
From Setup, enter CSP Trusted Sites in the Quick Find box, and then CSP Trusted Sites
Add your endpoint URL in Remote Site settings
Path:
From Setup, enter Remote Site in the Quick Find box, and then Remote Site Settings
Once you white-listed the endpoint URL now we are ready to create the component.
Once you white-listed the endpoint URL now we are ready to create the component.
Approach 1: Client-Side Controller
HTTPCalloutInLWC.html
<template>
<lightning-card title="Realtime Currency Exchange Rate" icon-name="standard:currency">
<lightning-layout multiple-rows="true" vertical-align="end">
<lightning-layout-item size="12" small-device-size="4" medium-device-size="2" large-device-size="2" padding="around-small">
<div class="slds-form-element">
<div class="slds-form-element__control">
<lightning-combobox title="Select Currency"
label="From Base Currency"
value={fromCurrencyValue}
placeholder="-Select-"
options={options}
onchange={handleFromCurrencyChange}></lightning-combobox>
</div>
</div>
</lightning-layout-item>
<lightning-layout-item size="12" small-device-size="4" medium-device-size="2" large-device-size="2" padding="around-small">
<div class="slds-form-element">
<div class="slds-form-element__control">
<lightning-combobox title="Select Currency"
label="To Currency"
value={toCurrencyValue}
placeholder="-Select-"
options={toCurrencyOptions}
onchange={handleToCurrencyChange}></lightning-combobox>
</div>
</div>
</lightning-layout-item>
<lightning-layout-item size="12" small-device-size="2" medium-device-size="2" large-device-size="2" padding="around-small">
<lightning-button title="Currency Conversion"
label="Conversion Rate"
variant="brand"
onclick={handleCurrencyConversion}></lightning-button>
</lightning-layout-item>
</lightning-layout><br/>
<template if:true={conversionData}>
<div class="slds-p-around_medium" id="modal-content-id-1">
<div style="font-size: 20px"><h1>Exchange rate from Currency <b>{fromCurrencyValue}</b> to <b>{toCurrencyValue}</b> </h1></div><br/>
<dl class="slds-list_horizontal slds-wrap">
<dt class="slds-item_label slds-truncate" title="From Currency Name">From Currency Name</dt>
<dd class="slds-item_detail slds-truncate"><b>: {conversionData.From_Currency_Name}</b></dd>
<dt class="slds-item_label slds-truncate" title="From Currency Code">From Currency Code</dt>
<dd class="slds-item_detail slds-truncate"><b>: {conversionData.From_Currency_Code}</b></dd>
<dt class="slds-item_label slds-truncate" title="To Currency Name">To Currency Name</dt>
<dd class="slds-item_detail slds-truncate"><b>: {conversionData.To_Currency_Name}</b></dd>
<dt class="slds-item_label slds-truncate" title="To Currency Code">To Currency Code</dt>
<dd class="slds-item_detail slds-truncate"><b>: {conversionData.To_Currency_Code}</b></dd>
<dt class="slds-item_label slds-truncate" title="Exchange Rate">Exchange Rate</dt>
<dd class="slds-item_detail slds-truncate">: <b style="color:red;">{conversionData.Exchange_Rate}</b></dd>
<dt class="slds-item_label slds-truncate" title="Last Refershed">Last Refereshed</dt>
<dd class="slds-item_detail slds-truncate"><b>: {conversionData.Last_Refershed}</b></dd>
</dl>
</div>
</template>
</lightning-card>
</template>
HTTPCalloutInLWC.js
HTTPCalloutInLWC.js-meta.xmlimport { LightningElement, track} from 'lwc';
// Currency options
const options = [
{ label: 'USD', value: 'USD' },
{ label: 'EUR', value: 'EUR' },
{ label: 'CAD', value: 'CAD' },
{ label: 'GBP', value: 'GBP' },
{ label: 'INR', value: 'INR' }];
export default class HTTPCalloutInLWC extends LightningElement {
@track fromCurrencyValue;
@track toCurrencyValue;
@track options = options;
@track toCurrencyOptions = options;
@track conversionData;
// Getting Base currency value
handleFromCurrencyChange(event) {
this.fromCurrencyValue = event.detail.value;
}
// getting exchange currency value
handleToCurrencyChange(event) {
this.toCurrencyValue = event.detail.value;
}
// Making Callout using Fetch
handleCurrencyConversion() {
fetch('https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency='
+ this.fromCurrencyValue + '&to_currency=' + this.toCurrencyValue + '&apikey=4W7NZUQNJ061YHHF', // End point URL
{
// Request type
method:"GET",
headers:{
// content type
"Content-Type": "application/json",
// adding your access token
"Authorization": "OAuth 00DB0000000EfVQ!AQwAQEiiynMU2EsBcS2PhXSQ6KQTTG.Zr0hlDHTFcGcAPqKQOBNDB0rwyASZK44fqIAVe6GrVNZPsAWJ6iqXLNBfSQ.dqvW1",
}
})
.then((response) => {
return response.json(); // returning the response in the form of JSON
})
.then((jsonResponse) => {
let objData = {
From_Currency_Name : '',
From_Currency_Code : '',
To_Currency_Name : '',
To_Currency_Code : '',
Exchange_Rate : '',
Last_Refersed : '',
};
window.console.log('jsonResponse ===> '+JSON.stringify(jsonResponse));
// retriving the response data
let exchangeData = jsonResponse['Realtime Currency Exchange Rate'];
// adding data object
objData.From_Currency_Code = exchangeData['1. From_Currency Code'];
objData.From_Currency_Name = exchangeData['2. From_Currency Name'];
objData.To_Currency_Code = exchangeData['3. To_Currency Code'];
objData.To_Currency_Name = exchangeData['4. To_Currency Name'];
objData.Exchange_Rate = exchangeData['5. Exchange Rate'];
objData.Last_Refershed = exchangeData['6. Last Refreshed'];
// adding data object to show in UI
this.conversionData = objData;
})
.catch(error => {
window.console.log('callout error ===> '+JSON.stringify(error));
})
}
}
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="HTTPCalloutInLWC">
<apiVersion>46.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>
Approach 2: Server-Side Controller
To make the callout using server-side I created apex class it accepts the endpoint URL.
Apex Class
public inherited sharing class CurrencyConversionController {
@AuraEnabled
public static map<String, Object> retriveCurrencyConversionRates(String strEndPointURL){
map<String, Object> mapJsonData = new map<String, Object>();
String strResponse = null;
if(String.isNotBlank(strEndPointURL)) {
HttpRequest httpRequest = new HttpRequest();
httpRequest.setEndpoint(strEndPointURL);
httpRequest.setMethod('GET');
httpRequest.setHeader('Authorization', 'OAuth ' + UserInfo.getSessionId());
httpRequest.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
try {
Http http = new Http();
HttpResponse httpResponse = http.send(httpRequest);
while(httpResponse.getStatusCode() == 302) {
httpRequest.setEndpoint(httpResponse.getHeader('Location'));
httpResponse = new Http().send(httpRequest);
}
if (httpResponse.getStatusCode() == 200 ) {
strResponse = httpResponse.getBody();
}
else {
throw new CalloutException(httpResponse.getBody());
}
}
catch(Exception ex) {
throw ex;
}
}
if(!String.isBlank(strResponse)) {
mapJsonData = (map<String, Object>)JSON.deserializeUntyped(strResponse);
System.debug('mapJsonData ===> '+mapJsonData);
}
if(!mapJsonData.isEmpty()) {
return mapJsonData;
}
else {
return null;
}
}
}
Import the Apex class method in JS controller
import getCurrencyData from '@salesforce/apex/CurrencyConversionController.retriveCurrencyConversionRates';
update JS Controller with below codeHTTPCalloutInLWC.js
import { LightningElement, track} from 'lwc';
// importing apex class to make callout
import getCurrencyData from '@salesforce/apex/CurrencyConversionController.retriveCurrencyConversionRates';
// Currency options
const options = [
{ label: 'USD', value: 'USD' },
{ label: 'EUR', value: 'EUR' },
{ label: 'CAD', value: 'CAD' },
{ label: 'GBP', value: 'GBP' },
{ label: 'INR', value: 'INR' }];
export default class HTTPCalloutInLWC extends LightningElement {
@track fromCurrencyValue;
@track toCurrencyValue;
@track options = options;
@track toCurrencyOptions = options;
@track conversionData;
// Getting Base currency value
handleFromCurrencyChange(event) {
this.fromCurrencyValue = event.detail.value;
}
// getting exchange currency value
handleToCurrencyChange(event) {
this.toCurrencyValue = event.detail.value;
}
// Making Callout using apex class
handleCurrencyConversion() {
// endpoint URL
let endpointURL = 'https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency='
+ this.fromCurrencyValue + '&to_currency=' + this.toCurrencyValue + '&apikey=4W7NZUQNJ061YHHF';
// calling apex class method to make callout
getCurrencyData({strEndPointURL : endpointURL})
.then(data => {
let objData = {
From_Currency_Name : '',
From_Currency_Code : '',
To_Currency_Name : '',
To_Currency_Code : '',
Exchange_Rate : '',
Last_Refersed : '',
};
window.console.log('jsonResponse ===> '+JSON.stringify(data));
// retriving the response data
let exchangeData = data['Realtime Currency Exchange Rate'];
// adding data object
objData.From_Currency_Code = exchangeData['1. From_Currency Code'];
objData.From_Currency_Name = exchangeData['2. From_Currency Name'];
objData.To_Currency_Code = exchangeData['3. To_Currency Code'];
objData.To_Currency_Name = exchangeData['4. To_Currency Name'];
objData.Exchange_Rate = exchangeData['5. Exchange Rate'];
objData.Last_Refershed = exchangeData['6. Last Refreshed'];
// adding data object to show in UI
this.conversionData = objData;
})
.catch(error => {
window.console.log('error ====> '+JSON.stringify(error));
})
}
}
Output
great..very helpful
ReplyDeleteIt's working fine in desktop application but not in mobile, Could you please let me know what changes I need to do for mobile.
ReplyDeleteWhere did you get the Authorization Code?
ReplyDeleteNevermind the SessionId question. I thought that was something provided by endpoint.
ReplyDeleteShould this work on mobile? I have it working on desktop, but maybe I'm missing some mobile configs... Can you provide some help here please?
ReplyDeletePlease use the form factors.
DeleteCheck this link to more about form factors.
https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.use_config_form_factors
Can you please add a tutorial about JEST testing this component? Thanks
ReplyDeleteThank you sir! This was a very helpful tutorial and filled in some gaps in my knowledge.
ReplyDelete