Component to fetch and display Country-wise COVID19 Data in Lightning Web Component
Components:
Covid19Data - Apex class for making callouts.
covid19LWC - Lightning Web Component for displaying the data from the callout.
Endpoint_Covid19 - Remote Site Settings to enable our Salesforce org to make callouts to the desired endpoint.
COVID 19 Data - Lightning Tab to accommodate covid19LWC.
-------------------- Covid19Data.apxc -----------------------
public class Covid19Data {
@AuraEnabled(cacheable=true)
public static List<wrapperData> getCovid19SummaryData(){
List<wrapperData> returnVal = new List<wrapperData>();
http h = new http();
httprequest req = new httprequest();
req.setEndpoint('https://api.covid19api.com/summary');
req.setHeader('Accept', 'application/json');
req.setMethod('GET');
req.setTimeout(12000);
httpresponse res = h.send(req);
if (res.getStatusCode() == 200) {
Map<String, Object> responseResult = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
List<Object> objects = (List<Object>) responseResult.get('Countries');
for(Object obj : objects){
wrapperData wrapperObj = new wrapperData();
String strResult = JSON.serialize(obj);
wrapperObj = (wrapperData) JSON.deserialize(strResult, wrapperData.class);
if(String.isNotBlank(wrapperObj.Country)) returnVal.add(wrapperObj);
}
}
return returnVal;
}
public class wrapperData{
@AuraEnabled
public string Country;
@AuraEnabled
public integer NewConfirmed;
@AuraEnabled
public integer TotalConfirmed;
@AuraEnabled
public integer NewDeaths;
@AuraEnabled
public integer TotalDeaths;
@AuraEnabled
public integer NewRecovered;
@AuraEnabled
public integer TotalRecovered;
}
}
--------------------------------- covid19LWC components ---------------------------
covid19LWC.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>48.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__Tab</target>
</targets>
</LightningComponentBundle>
covid19LWC.html
<template>
<div if:true={isLoading} class="cstm-spinner">
<lightning-spinner alternative-text="Loading..."></lightning-spinner>
</div>
<div class="slds-m-bottom_small">
<lightning-card>
<!--<div class="slds-align_absolute-center">-->
<lightning-layout>
<lightning-layout-item class="slds-p-left_small">
<lightning-icon icon-name="action:freeze_user"></lightning-icon>
</lightning-layout-item>
<lightning-layout-item>
<p class="slds-p-horizontal_small"><b>COVID19</b></p>
<p class="slds-p-horizontal_small" style="color: #7d7373;">Data from COVID19 API</p>
<a href="https://documenter.getpostman.com/view/10808728/SzS8rjbc?version=latest">
<p class="slds-p-horizontal_small">
https://documenter.getpostman.com/
</p>
</a>
</lightning-layout-item>
</lightning-layout>
<!--</div>-->
</lightning-card>
</div>
<div if:true={isData} class="slds-m-bottom_small">
<lightning-card >
<lightning-layout>
<lightning-layout-item class="slds-p-left_small">
<lightning-icon icon-name="custom:custom109"></lightning-icon>
</lightning-layout-item>
<lightning-layout-item>
<p class="slds-p-horizontal_small slds-p-top_xx-small"><b>Data for {covid19Data.length} countries</b></p>
</lightning-layout-item>
</lightning-layout>
<lightning-layout>
<lightning-layout-item class="slds-p-around_x-small" size="12">
<table
class="slds-table slds-table_cell-buffer slds-table_bordered slds-max-medium-table_stacked-horizontal"
style="background-color: #d5e9a0;">
<thead>
<th class="" scope="col">
<div class="slds-truncate" title="Total Cases">Total Cases</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="Total Deaths">Total Deaths</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="Total Recovered">Total Recovered</div>
</th>
</thead>
<tbody>
<tr data-target-id = 'eachRow' class="slds-hint-parent">
<td data-label="Total Cases">
<div class="slds-truncate" title="">{totalCases}</div>
</td>
<td data-label="Total Deaths">
<div class="slds-truncate" title="">{totalDeaths}</div>
</td>
<td data-label="Total Recovered">
<div class="slds-truncate" title="">{totalRecovered}</div>
</td>
</tr><br/>
</tbody>
</table>
</lightning-layout-item>
</lightning-layout>
</lightning-card>
</div>
<lightning-card>
<lightning-layout if:true={isData} >
<lightning-layout-item class="slds-p-left_small">
<p class="slds-p-horizontal_small"><b>Country-wise Data</b></p><br/>
</lightning-layout-item>
</lightning-layout>
<div class="slds-p-around_small">
<lightning-layout multiple-rows if:true={isData} style="width:100%">
<lightning-layout-item style="width: 100%;">
<template if:true={showMobileView}>
<div class="slds-scrollable" style="height:35rem;">
<table class="slds-table slds-table_cell-buffer slds-table_bordered slds-max-medium-table_stacked-horizontal">
<thead>
<th class="" scope="col">
<div class="slds-truncate" title="Country">Country</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="New Confirmed">New Confirmed</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="Total Confirmed">Total Confirmed</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="New Deaths">New Deaths</div>
</th>
<th class="" scope="col" style="background-color:indianred">
<div class="slds-truncate" title="Total Deaths">Total Deaths</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="New Recovered">New Recovered</div>
</th>
<th class="" scope="col" style="background-color: lawngreen;">
<div class="slds-truncate" title="Total Recovered">Total Recovered</div>
</th>
</tr>
</thead>
<tbody>
<template for:each={covid19Data} for:item="eachData">
<tr data-target-id = 'eachRow' class="slds-hint-parent" key={eachData.Country}>
<td data-label="Country">
<div class="slds-truncate" title="">{eachData.Country}</div>
</td>
<td data-label="New Confirmed">
<div class="slds-truncate" title="">{eachData.NewConfirmed}</div>
</td>
<td data-label="Total Confirmed">
<div class="slds-truncate" title="">{eachData.TotalConfirmed}</div>
</td>
<td data-label="New Deaths">
<div class="slds-truncate" title="">{eachData.NewDeaths}</div>
</td>
<td data-label="Total Deaths" style="background-color:indianred">
<div class="slds-truncate" title="">{eachData.TotalDeaths}</div>
</td>
<td data-label="New Recovered">
<div class="slds-truncate" title="">{eachData.NewRecovered}</div>
</td>
<td data-label="Total Recovered" style="background-color:lawngreen;">
<div class="slds-truncate" title="" >{eachData.TotalRecovered}</div>
</td>
</tr>
</template>
</tbody>
</table>
</div>
</template>
<template if:false={showMobileView}>
<div class="slds-scrollable" style="height:15rem;">
<table class="slds-table slds-table_cell-buffer slds-table_bordered slds-max-medium-table_stacked-horizontal">
<thead>
<th class="" scope="col">
<div class="slds-truncate" title="Country">Country</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="New Confirmed">New Confirmed</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="Total Confirmed">Total Confirmed</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="New Deaths">New Deaths</div>
</th>
<th class="" scope="col" style="background-color:indianred">
<div class="slds-truncate" title="Total Deaths">Total Deaths</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="New Recovered">New Recovered</div>
</th>
<th class="" scope="col" style="background-color: lawngreen;">
<div class="slds-truncate" title="Total Recovered">Total Recovered</div>
</th>
</tr>
</thead>
<tbody>
<template for:each={covid19Data} for:item="eachData">
<tr data-target-id = 'eachRow' class="slds-hint-parent" key={eachData.Country}>
<td data-label="Country">
<div class="slds-truncate" title="">{eachData.Country}</div>
</td>
<td data-label="New Confirmed">
<div class="slds-truncate" title="">{eachData.NewConfirmed}</div>
</td>
<td data-label="Total Confirmed">
<div class="slds-truncate" title="">{eachData.TotalConfirmed}</div>
</td>
<td data-label="New Deaths">
<div class="slds-truncate" title="">{eachData.NewDeaths}</div>
</td>
<td data-label="Total Deaths" style="background-color:indianred">
<div class="slds-truncate" title="">{eachData.TotalDeaths}</div>
</td>
<td data-label="New Recovered">
<div class="slds-truncate" title="">{eachData.NewRecovered}</div>
</td>
<td data-label="Total Recovered" style="background-color:lawngreen;">
<div class="slds-truncate" title="" >{eachData.TotalRecovered}</div>
</td>
</tr>
</template>
</tbody>
</table>
</div>
</template>
</lightning-layout-item>
</lightning-layout>
</div>
</lightning-card>
</template>
covid19LWC.js
import { LightningElement, track} from 'lwc';
import FORM_FACTOR from '@salesforce/client/formFactor';
import getCovid19SummaryData from '@salesforce/apex/Covid19Data.getCovid19SummaryData';
export default class Covid19LWC extends LightningElement {
@track covid19Data = [];
isData = false;
isLoading = false;
totalCases = 0;
totalDeaths = 0;
totalRecovered = 0;
showMobileView = false;
connectedCallback() {
this.isLoading = true;
this.formFactor = FORM_FACTOR;
if(this.formFactor == 'Small') this.showMobileView = true;
getCovid19SummaryData()
.then(result => {
if(result){
this.covid19Data = result;
this.isData = true;
this.isLoading = false;
for(var i=0; i<result.length; i++){
this.totalCases += result[i].TotalConfirmed;
this.totalDeaths += result[i].TotalDeaths;
this.totalRecovered += result[i].TotalRecovered;
}
}else{
this.isLoading = false;
}
})
.catch(error => {
this.isLoading = false;
});
}
}
Note: The Data is being fetched from the public API (Click here for reference).
Components:
Covid19Data - Apex class for making callouts.
covid19LWC - Lightning Web Component for displaying the data from the callout.
Endpoint_Covid19 - Remote Site Settings to enable our Salesforce org to make callouts to the desired endpoint.
COVID 19 Data - Lightning Tab to accommodate covid19LWC.
-------------------- Covid19Data.apxc -----------------------
public class Covid19Data {
@AuraEnabled(cacheable=true)
public static List<wrapperData> getCovid19SummaryData(){
List<wrapperData> returnVal = new List<wrapperData>();
http h = new http();
httprequest req = new httprequest();
req.setEndpoint('https://api.covid19api.com/summary');
req.setHeader('Accept', 'application/json');
req.setMethod('GET');
req.setTimeout(12000);
httpresponse res = h.send(req);
if (res.getStatusCode() == 200) {
Map<String, Object> responseResult = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
List<Object> objects = (List<Object>) responseResult.get('Countries');
for(Object obj : objects){
wrapperData wrapperObj = new wrapperData();
String strResult = JSON.serialize(obj);
wrapperObj = (wrapperData) JSON.deserialize(strResult, wrapperData.class);
if(String.isNotBlank(wrapperObj.Country)) returnVal.add(wrapperObj);
}
}
return returnVal;
}
public class wrapperData{
@AuraEnabled
public string Country;
@AuraEnabled
public integer NewConfirmed;
@AuraEnabled
public integer TotalConfirmed;
@AuraEnabled
public integer NewDeaths;
@AuraEnabled
public integer TotalDeaths;
@AuraEnabled
public integer NewRecovered;
@AuraEnabled
public integer TotalRecovered;
}
}
--------------------------------- covid19LWC components ---------------------------
covid19LWC.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>48.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__Tab</target>
</targets>
</LightningComponentBundle>
covid19LWC.html
<template>
<div if:true={isLoading} class="cstm-spinner">
<lightning-spinner alternative-text="Loading..."></lightning-spinner>
</div>
<div class="slds-m-bottom_small">
<lightning-card>
<!--<div class="slds-align_absolute-center">-->
<lightning-layout>
<lightning-layout-item class="slds-p-left_small">
<lightning-icon icon-name="action:freeze_user"></lightning-icon>
</lightning-layout-item>
<lightning-layout-item>
<p class="slds-p-horizontal_small"><b>COVID19</b></p>
<p class="slds-p-horizontal_small" style="color: #7d7373;">Data from COVID19 API</p>
<a href="https://documenter.getpostman.com/view/10808728/SzS8rjbc?version=latest">
<p class="slds-p-horizontal_small">
https://documenter.getpostman.com/
</p>
</a>
</lightning-layout-item>
</lightning-layout>
<!--</div>-->
</lightning-card>
</div>
<div if:true={isData} class="slds-m-bottom_small">
<lightning-card >
<lightning-layout>
<lightning-layout-item class="slds-p-left_small">
<lightning-icon icon-name="custom:custom109"></lightning-icon>
</lightning-layout-item>
<lightning-layout-item>
<p class="slds-p-horizontal_small slds-p-top_xx-small"><b>Data for {covid19Data.length} countries</b></p>
</lightning-layout-item>
</lightning-layout>
<lightning-layout>
<lightning-layout-item class="slds-p-around_x-small" size="12">
<table
class="slds-table slds-table_cell-buffer slds-table_bordered slds-max-medium-table_stacked-horizontal"
style="background-color: #d5e9a0;">
<thead>
<th class="" scope="col">
<div class="slds-truncate" title="Total Cases">Total Cases</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="Total Deaths">Total Deaths</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="Total Recovered">Total Recovered</div>
</th>
</thead>
<tbody>
<tr data-target-id = 'eachRow' class="slds-hint-parent">
<td data-label="Total Cases">
<div class="slds-truncate" title="">{totalCases}</div>
</td>
<td data-label="Total Deaths">
<div class="slds-truncate" title="">{totalDeaths}</div>
</td>
<td data-label="Total Recovered">
<div class="slds-truncate" title="">{totalRecovered}</div>
</td>
</tr><br/>
</tbody>
</table>
</lightning-layout-item>
</lightning-layout>
</lightning-card>
</div>
<lightning-card>
<lightning-layout if:true={isData} >
<lightning-layout-item class="slds-p-left_small">
<p class="slds-p-horizontal_small"><b>Country-wise Data</b></p><br/>
</lightning-layout-item>
</lightning-layout>
<div class="slds-p-around_small">
<lightning-layout multiple-rows if:true={isData} style="width:100%">
<lightning-layout-item style="width: 100%;">
<template if:true={showMobileView}>
<div class="slds-scrollable" style="height:35rem;">
<table class="slds-table slds-table_cell-buffer slds-table_bordered slds-max-medium-table_stacked-horizontal">
<thead>
<th class="" scope="col">
<div class="slds-truncate" title="Country">Country</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="New Confirmed">New Confirmed</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="Total Confirmed">Total Confirmed</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="New Deaths">New Deaths</div>
</th>
<th class="" scope="col" style="background-color:indianred">
<div class="slds-truncate" title="Total Deaths">Total Deaths</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="New Recovered">New Recovered</div>
</th>
<th class="" scope="col" style="background-color: lawngreen;">
<div class="slds-truncate" title="Total Recovered">Total Recovered</div>
</th>
</tr>
</thead>
<tbody>
<template for:each={covid19Data} for:item="eachData">
<tr data-target-id = 'eachRow' class="slds-hint-parent" key={eachData.Country}>
<td data-label="Country">
<div class="slds-truncate" title="">{eachData.Country}</div>
</td>
<td data-label="New Confirmed">
<div class="slds-truncate" title="">{eachData.NewConfirmed}</div>
</td>
<td data-label="Total Confirmed">
<div class="slds-truncate" title="">{eachData.TotalConfirmed}</div>
</td>
<td data-label="New Deaths">
<div class="slds-truncate" title="">{eachData.NewDeaths}</div>
</td>
<td data-label="Total Deaths" style="background-color:indianred">
<div class="slds-truncate" title="">{eachData.TotalDeaths}</div>
</td>
<td data-label="New Recovered">
<div class="slds-truncate" title="">{eachData.NewRecovered}</div>
</td>
<td data-label="Total Recovered" style="background-color:lawngreen;">
<div class="slds-truncate" title="" >{eachData.TotalRecovered}</div>
</td>
</tr>
</template>
</tbody>
</table>
</div>
</template>
<template if:false={showMobileView}>
<div class="slds-scrollable" style="height:15rem;">
<table class="slds-table slds-table_cell-buffer slds-table_bordered slds-max-medium-table_stacked-horizontal">
<thead>
<th class="" scope="col">
<div class="slds-truncate" title="Country">Country</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="New Confirmed">New Confirmed</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="Total Confirmed">Total Confirmed</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="New Deaths">New Deaths</div>
</th>
<th class="" scope="col" style="background-color:indianred">
<div class="slds-truncate" title="Total Deaths">Total Deaths</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="New Recovered">New Recovered</div>
</th>
<th class="" scope="col" style="background-color: lawngreen;">
<div class="slds-truncate" title="Total Recovered">Total Recovered</div>
</th>
</tr>
</thead>
<tbody>
<template for:each={covid19Data} for:item="eachData">
<tr data-target-id = 'eachRow' class="slds-hint-parent" key={eachData.Country}>
<td data-label="Country">
<div class="slds-truncate" title="">{eachData.Country}</div>
</td>
<td data-label="New Confirmed">
<div class="slds-truncate" title="">{eachData.NewConfirmed}</div>
</td>
<td data-label="Total Confirmed">
<div class="slds-truncate" title="">{eachData.TotalConfirmed}</div>
</td>
<td data-label="New Deaths">
<div class="slds-truncate" title="">{eachData.NewDeaths}</div>
</td>
<td data-label="Total Deaths" style="background-color:indianred">
<div class="slds-truncate" title="">{eachData.TotalDeaths}</div>
</td>
<td data-label="New Recovered">
<div class="slds-truncate" title="">{eachData.NewRecovered}</div>
</td>
<td data-label="Total Recovered" style="background-color:lawngreen;">
<div class="slds-truncate" title="" >{eachData.TotalRecovered}</div>
</td>
</tr>
</template>
</tbody>
</table>
</div>
</template>
</lightning-layout-item>
</lightning-layout>
</div>
</lightning-card>
</template>
covid19LWC.js
import { LightningElement, track} from 'lwc';
import FORM_FACTOR from '@salesforce/client/formFactor';
import getCovid19SummaryData from '@salesforce/apex/Covid19Data.getCovid19SummaryData';
export default class Covid19LWC extends LightningElement {
@track covid19Data = [];
isData = false;
isLoading = false;
totalCases = 0;
totalDeaths = 0;
totalRecovered = 0;
showMobileView = false;
connectedCallback() {
this.isLoading = true;
this.formFactor = FORM_FACTOR;
if(this.formFactor == 'Small') this.showMobileView = true;
getCovid19SummaryData()
.then(result => {
if(result){
this.covid19Data = result;
this.isData = true;
this.isLoading = false;
for(var i=0; i<result.length; i++){
this.totalCases += result[i].TotalConfirmed;
this.totalDeaths += result[i].TotalDeaths;
this.totalRecovered += result[i].TotalRecovered;
}
}else{
this.isLoading = false;
}
})
.catch(error => {
this.isLoading = false;
});
}
}
Can you expose this on a community page and make it public
ReplyDeleteThis comment has been removed by the author.
DeleteThis comment has been removed by the author.
ReplyDeleteI used your code and try to implement the same. When i push code from VS code to one of the scratch org the push is geeting failed as "XML parse error: Unexpected xml:" in covid19LWC.js.
ReplyDeletecan you just help me out here if I am missing any.
lightning__AppPage>
ReplyDeletethere was additional greater than in above syntax which was causing the error.Removing one fixed the Issue.
Thank you.
Hi There,
DeleteThanks for letting me know.
This comment has been removed by the author.
ReplyDeleteCool, really appreciate that you are replicating this in your orgs.. Keep up the hard work :) (y)
ReplyDelete