Part-4 REST API callout from lwc

Let us try to know about how to get the data from any other 3rd party source (lets say SAP module) to lightning web component (lwc), by making a REST API callout from Salesforce, and display it in a lightning web component (lwc)..

In other words

lets integrate Salesforce with any other system, where salesforce acts as client, while third party system provides the service.

Generally, We can make a callout from Salesforce in 2 ways

  1. From Client-side controller (from javascript class – ES6)
  2. From Server-side controller (from Apex class)

After having the required apis and a URL to hit..(lets say we are going to hit URL for retrieving data), if we decide to go for :

Client-Side Callout :

Then don’t forget to white-list the endpoint in Content Security Policies (CSP)

Click Setup —> CSP

Server-Side callout :

Then don’t forget to white-list the endpoint in Remote-Site Settings.

Click Setup —> Remote Site

For the purpose of learning / demo, we need to get the 2nd system with apis. From which we wish to pull out the data.. api dictionary – programmable web contains apis of most commonly known systems / websites / companies..

We will choose moviesDB, for example our motive is, whenever we click on a button in lightning card, it displays the list of movies.. now playing in theaters. SO LETS START…!

  1. create an account in themoviesdb.org
  2. click on api tab, and get api key / accesstoken
  3. Observe the api documentation and lets hit the URL, which displays the list of movies released in India in last 1 month and Now Playing in theatres.

Appropriate endpoint URL, to hit is shown below..

NOTE : While registering for API choose the purpose as EDUCATION, I don’t hold any official licence to use it for testing / learning

https://api.themoviedb.org/3/movie/now_playing?api_key=52121b8ffd37db19123c9f47321e259c&language=te-IN&region=IN

If sfdx CLI and Visual studio code are installed, Please point your command line to a folder where you wish to create an sfdx project.. execute the below commands one after the other.

cd path/to/your/sfdx/projects
sfdx force:project:create --projectname friday-poster
cd friday-poster
sfdx force:lightning:component:create --type lwc -n fetch -d force-app/main/default/lwc

So, our project Name is friday-poster and component name is fetch

Browse to fetch folder and create a JavaScript file with name movie.js, paste the following code and save it

export default class Movie{
	
	constructor(Id, title, original_language, overview, vote_average, release_date, poster_path) {
		this._id = Id;
		this._title = title;
		this._original_language = original_language;
		this._overview = overview;
		this._vote_average = vote_average;
		this._release_date = release_date;
		this._poster_path  = "https://image.tmdb.org/t/p/w300"+poster_path;
	}
}

Project structure is shown below.

Paste the following code in fetch.js

import { LightningElement,track} from 'lwc';
import Movie from './movie';
export default class Fetch extends LightningElement {
	
	
	@track movies;
	
	handleCallout(){
		fetch('https://api.themoviedb.org/3/movie/now_playing?api_key=52121b8ffd37db19123c9f47321e259c&region=IN',
		{
			method : "GET",
			headers : {
				"Content-Type": "application/json",
				"Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI1MjEyMWI4ZmZkMzdkYjE5MTIzYzlmNDczMjFlMjU5YyIsInN1YiI6IjVjNDc0NWFmMGUwYTI2NDk2NWNhNGFhZiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.tdMnNkQfXU__PtQSCyB-XPBJ3FJtIVwlU86LBJHeURU"
			}
		}).then(function(response) {
			return response.json();
		})
		.then((myJson) =>{
			// console.log('%%%%'+JSON.stringify(myJson));
			let movies_list = [];
			for(let v of Object.values(myJson.results)){
				// console.log('%%%%'+JSON.stringify(v.title));
				// console.log('$$$$'+v.title);
				movies_list.push(new Movie(v.Id, v.title, v.original_language, v.overview, v.vote_average, v.release_date, v.poster_path));
			}
			
			// console.log('*****'+JSON.stringify(movies_list));
			
			this.movies = movies_list;
			
		})
		.catch(e=>console.log(e));
	}
}

fetch.html

<template>
       <lightning-card title="Callout" icon-name="standard:product_consumed">
        <div class="slds-m-around_medium">
            <lightning-button label="get movies playing now" variant="brand" onclick={handleCallout} class="slds-p-vertical_small"></lightning-button>
               <!-- hello -->
        </div>
                <template for:each={movies} for:item="movie">
                    <c-movie-tile
                    key={movie._Id}
                    title={movie._title}
                    language={movie._original_language}
                    overview={movie._overview}
                    vote={movie._vote_average}
                    release-date={movie._release_date}
                    poster-path={movie._poster_path}
                    class="slds-m-around_xx-large"
                    >
                    </c-movie-tile>
					<br key={movie._Id}/>
                </template>
    </lightning-card>
</template>

movieTile.html

<template>
    <div class="content slds-m-around_x-large">
        <img
            src={posterPath}
            class="slds-align_absolute-center"
            alt="movie poster"
        />
        <br/>
       <div class="slds-m-horizontal_x-small">
       <lightning-card >
        <div>
            <p class="title slds-align_absolute-center">{title}<br/><br/></p>
            <p class="slds-align_absolute-center">RELEASE DATE : {releaseDate}</p>
            <p class="slds-align_absolute-center">RATING : {vote} / 10 </p>
            <p class="slds-align_absolute-center">LANGUAGE : {language}<br/></p>
            <div class="slds-m-horizontal_medium">
                <p>STORY : {overview}</p>
            </div>
        </div>
       </lightning-card>
    </div>
    </div>
</template>

movieTile.js

import { LightningElement, api } from 'lwc';

export default class MovieTile extends LightningElement {
    
    @api posterPath;
    @api title;
    @api releaseDate;
    @api vote;
    @api language;
    @api Id;
    @api overview;
}

movieTile.css

.content {
    padding: 8px;
    background-color: #eaeaea;
    border-radius: 0.5rem;
}
.title {
    font-weight: bold;
    text-transform: uppercase;
}

Now deploy this component.. behavior of component is shown below.

After clicking on get movies button..


I will soon come up with an-other version of this article, in much more Neater and Structurized way with more functionalities added to this lwc..

In this version 2 of this article, i have added parent-to-child composition functionality and movieTile component is iterated.. in fetch component

An Integration is an Integration, whether we do it with a banking database system or movies database. [next version of this article is under construction]

Comments (5)

  1. veera says:

    hi srikanth,

    Above fetch Code giving error ,

    “SyntaxError: Unexpected end of input”

    Any idea. Why this error coming .

    Thanks
    Veera

  2. Amre says:

    Hello,
    Thank your very much for the article.
    I have a question please :
    What is the best practice ?
    Make callout client-side from Javascript or server-side from APEX ?
    I don’t know what it the main difference between the two.
    Thank you.

  3. Ethan says:

    Even with the CSP and the Remote site set, i keep getting this error:
    Refused to connect to ‘https://api.themoviedb.org/3/movie/now_playing?api_key=193603fd797bc5351&region=IN’ because it violates the document’s Content Security Policy.

  4. Rijwan says:

    how can we post input file in lightning component

Leave a Reply

Your email address will not be published. Required fields are marked *