HTTP callout from LWC

HTTP callout from Lightning Web Components? Is it similar to Lightning (Aura) components? Or is something better available in modern JavaScript? Do we still require Apex to make the callout? Or can we handle it all on the client side itself? Have similar questions in your mind? Then continue reading this blog post.

Today, we will see how to make an HTTP callout from a Lightning Web Component. Good news - we do not require any apex class to make the callout. In the JavaScript controller of our lightning web component, we can easily make the web service callout by making use of the fetch method.

For this example, we will use the free API provided by Crypto Compare. The API returns the response in JSON format, which we will parse and feed to the HTML file. The component will make the HTTP callout to bring in the price of the top 10 cryptocurrencies and display them in a lightning card.
To make the callout from the Lightning web component, first, we need to add the endpoint URL in the CSP Trusted Sites. In Setup, type CSP Trusted Sites and add the endpoint URL - https://min-api.cryptocompare.com


Now let's have a look at the Lightning Web Component that we will create. The name of the component is cryptoDisplay and the folder structure is given below:

cryptoDisplay.html is the HTML file for the component, whose JS controller is cryptoDisplay.js. There is an additional file named cryptoCurrencyInfo.js which will be used to store the response of the HTTP callout. Now let us have a look at the codebase:
cryptoDisplay.html
<template>
  <template for:each={cryptoInfo} for:item="info">
    <lightning-card key={info._name}>
      <h3 slot="title">
        <lightning-avatar src={info._image}></lightning-avatar>
        <lightning-badge label={info._name}></lightning-badge>
        <lightning-badge label={info._price}></lightning-badge>
      </h3>
    </lightning-card>
  </template>
</template>
The HTML markup is pretty straight forward, thanks to the base componets provided by LWC. The {cryptoInfo} is a list which is iterated using the template for:each, inside which we are creating instance of lightning-card to display the information.
cryptoDisplay.js
import { LightningElement, track } from "lwc";
import CryptoCurrencyInfo from "./cryptoCurrencyInfo";
export default class CryptoDisplay extends LightningElement {
  @track cryptoInfo;
  connectedCallback() {
    fetch(
      "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=BTC,ETH,XRP,EOS,BCH,LINK,LTC,TRX,ETC,BNB&tsyms=USD"
    )
      .then(function(response) {
        return response.json();
      })
      .then(responseJSON => {
        let cryptoList = [];
        Object.keys(responseJSON.RAW).forEach(function(key) {
          cryptoList.push(
            new CryptoCurrencyInfo(
              responseJSON.RAW[key].USD.FROMSYMBOL,
              "$ " + responseJSON.RAW[key].USD.PRICE,
              "https://www.cryptocompare.com/" +
                responseJSON.RAW[key].USD.IMAGEURL
            )
          );
        });
        this.cryptoInfo = cryptoList;
      });
  }
}
The intresting part of the game is happening inside the JS controller. Here we make an HTTP callout using the fetch method. This kind of functionality was earlier achieved using XMLHttpRequest. The basic format of fetch is as given below:
fetch(url)
  .then(response.something) // Define response type (JSON, Headers, Status codes)
  .then(data) // get the response type 
So using the fetch, we make the HTTP callout, which returns us the response in the form of a JSON string. The JSON string, in this case, is an object of object of object. So we need to parse 3 levels deep in order to get the actual information.
To store the information, we have created a JavaScript class named CryptoCurrencyInfo. This is similar to the wrapper class that we create in Apex to store the response of a web service callout.
CryptoCurrencyInfo.js
export default class CryptoCurrencyInfo {
  constructor(name, price, image) {
    this._name = name;
    this._price = price;
    this._image = image;
  }
}
In this class, we have created a constructor that accepts 3 parameters - name, price and the image of a specific cryptocurrency. You can add more attributes if you want to store some additional information.
To expose this component in the app builder, we need to create a meta xml file called cryptoDisplay.js-meta.xml with below content.
cryptoDisplay.js-meta.xml 
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="cryptoDisplay">
    <apiVersion>46.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>
The value of isExposed equals true makes the component available in the App builder, from where you can drag it into the page types specified in the targets attribute.
If you have any question, feel free to drop a comment.

Comments

Post a Comment

Popular posts from this blog

Salesforce Lightning: Countdown timer

Salesforce Hacks: System.LimitException: Too many queueable jobs added to the queue: 2

Building an Org Role Hierarchy component in LWC