LWC | Call External APIs from JavaScript

The Lightning Component framework controls the source of content that can be loaded on a page by using Content Security Policy (CSP), a W3C standard. API calls from JavaScript code are not permitted by the default CSP policy.

Q. What is CSP?

CSP is a W3C standard that defines rules for controlling the content source that can be loaded on a page. All CSP rules apply to all components and libraries at the page level. Web browsers use CSP rules specified in web page headers to block requests for resources such as scripts, images, and other data from unknown servers. CSP directives are also applicable to client-side JavaScript, such as restricting inline JavaScript in HTML.

By default, LWC JavaScript code cannot connect to WebSockets or call third-party APIs. We have to add a remote site as a CSP Trusted Site in our Salesforce org to accomplish this task.

Content security policy (CSP) is used by the Lightning Component framework to restrict content. The main goal is to aid in the prevention of cross-site scripting (XSS) and other code injection attacks.

Let’s add CSP trusted site to Salesforce org in order to make an API call from javascript code without error.

In this example, I’ll use the data-faker API hosted on Heroku: this is the endpoint https://data-faker.herokuapp.com that I’ll use to make a callout from javascript code.

Go to setup > search ‘ CSP ‘ > click on CSP Trusted Sites

CSP Trusted Site Setting in Salesforce
CSP Trusted Site Settings

Create a CSP trusted site by clicking on ‘New Trusted Site,’ as shown in the screenshot below.

CSP Trusted Site Creation

We are now ready to make a callout from javascript code in the lightning web component. Let’s build a lightning web component that retrieves data from the Heroku data-faker API and displays it in the lightning data table.

const recordMetadata = {
name: 'name',
email: 'email',
website: 'url',
amount: 'currency',
phone: 'phoneNumber',
closeAt: 'dateInFuture',
};
const ENDPOINT ='https://data-faker.herokuapp.com/collection'; //API endpoint
const POST_METHOD = 'POST'; //POST method
const CONTENT_TYPE = 'application/json; charset=utf-8';
export default function fetchDataHelper({ amountOfRecords }) {
/* The global fetch() method starts the process of fetching a resource from the network,
returning a promise which is fulfilled once the response is available.
*/
return fetch(ENDPOINT, {
method: POST_METHOD,
headers: {
'Content-Type': CONTENT_TYPE,
},
body: JSON.stringify({
amountOfRecords,
recordMetadata,
}),
}).then((response) => response.json());
}

The global fetch() method initiates the process of retrieving a resource from the network and returns a promise that is fulfilled once the response is available.

The promise resolves to the Response object, which represents our request’s response.

Syntax
fetch(resource)
fetch(resource, init)
Parameters

resource

This specifies the resource that you want to retrieve. This can be either:

  • A string or any other object with a stringifier, including a URL object, containing the URL of the resource to be retrieved.
  • A Request object.

init ( Optional )

An object containing any custom settings to be applied to the request. The possible options are:

NameDescription
methodThe request method, such as GET or POST. The Origin header is not set on Fetch requests with the HEAD or GET methods. 
headersAny additional headers you want to include in your request should be contained within a Headers object or an object literal with String values. It should be noted that some names are prohibited.
bodyAny object that you want to include in your request: a Blob, BufferSource, FormData, URLSearchParams, string, or ReadableStream object. A request made with the GET or HEAD methods cannot have a body.
modeThe mode for the request, such as cors, no-cors, or same-origin.
credentialsControls how browsers handle credentials (cookies, HTTP authentication entries, and TLS client certificates).
cacheA string indicating how the request will interact with the HTTP cache of the browser. The cache property of the Request object has the following possible values: default, no-store, reload, no-cache, force-cache, and only-if-cached.

Find more information here.

<template>
<lightning-card title="Data Table" icon-name="utility:table">
<div style="height: 400px;">
<lightning-datatable
key-field="id"
data={data}
columns={columns}
>
</lightning-datatable>
</div>
</lightning-card>
</template>
import { LightningElement } from 'lwc';
//import the helper javascript module/file
import fetchDataHelper from './fetchDataHelper';
const columns = [
{ label: 'Label', fieldName: 'name' },
{ label: 'Website', fieldName: 'website', type: 'url' },
{ label: 'Phone', fieldName: 'phone', type: 'phone' },
{ label: 'Balance', fieldName: 'amount', type: 'currency' },
{ label: 'CloseAt', fieldName: 'closeAt', type: 'date' },
];
export default class LightningTable extends LightningElement {
data = [];
columns = columns;
// async-await method
async connectedCallback() {
const data = await fetchDataHelper({ amountOfRecords: 100 });
this.data = data;
}
}

In the screenshot below, you can see data retrieved from the API displayed in the data table.

GitHub Repository

Call External APIs from JavaScript – Lightning Web Component

Arun Kumar

Arun Kumar is a Certified Salesforce developer and Salesforce Champions (Platform Champions), a Computer Science graduate, working on the Salesforce platform and providing customer solutions using force.com as a Salesforce consultant/developer. He is the founder of SFDCLessons. :)

Leave a Reply