Monday, March 30, 2020

Component to fetch and display Country-wise COVID19 Data in Lightning Web Component


                 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;
        });
    }
}

8 comments:

  1. Can you expose this on a community page and make it public

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. I 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.

    can you just help me out here if I am missing any.

    ReplyDelete
  4. lightning__AppPage>

    there was additional greater than in above syntax which was causing the error.Removing one fixed the Issue.

    Thank you.

    ReplyDelete
    Replies
    1. Hi There,
      Thanks for letting me know.

      Delete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Cool, really appreciate that you are replicating this in your orgs.. Keep up the hard work :) (y)

    ReplyDelete