How to get Listview records in Lwc


                                                                 Hello guys,
Today in this post we will learn how to get listview records in Lwc. In earlier, we used to get listview records by using getListUi but after  it was Deprecated(outdated) we have found  another way to getting listview records in lwc.
In this video we are getting dynamic listview records. 

First of all we need to create a vf page to get session Id And we are using getListInfoByName for fatch listview columns.

Let's go to practical.

Step 1 : GetSessionIdOnLWC.Vfp
<apex:page >
Start_Of_Session_id{!$Api.Session_ID}End_Of_Session_Id
</apex:page>
Step 2 : listViewNewVersionCtrl
/* Author : Ravi Soni
   Date   : 16 Oct 2021
   Content: dynmic Listview In Lwc
*/

public with sharing class listViewNewVersionCtrl {
    @AuraEnabled(cacheable=true)
    public static list<listView> fetchListView(string objectApiName){
        list<listView> lstListView = [SELECT Id, Name, DeveloperName, SobjectType FROM ListView
                                      WHERE sobjectType =: objectApiName ORDER by DeveloperName Asc];
    return lstListView;
    }
   
   @AuraEnabled(cacheable = true)
    public static List<sObject> getListviewRecords(String listviewId, string objectApiName){
        HttpRequest req = new HttpRequest();
		String baseUrl = URL.getSalesforceBaseUrl().toExternalForm();
		String endPoinURL = baseUrl+'/services/data/v52.0/sobjects/' + objectApiName + '/listviews/'+listviewId+'/describe';
		string sessionId = getSessionIdForLWC();
		req.setEndpoint(endPoinURL);
		req.setMethod('GET');
		req.setHeader('Authorization', 'Bearer ' + sessionId);
		Http http = new Http();
		HTTPResponse response = http.send(req);
        Map<String, Object> tokenResponse = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
        String query = (String) tokenResponse.get('query');
    	List<sObject> sobjectList = new List<sObject>();
		for(sObject obj : database.query(query)){
            sobjectList.add(obj);
		}
    	return sobjectList;

	}
    
     public static string getSessionIdForLWC(){
        pageReference pr = Page.GetSessionIdOnLWC;
        string content = pr.getContent().toString();
        integer startp = content.indexOf('Start_Of_Session_id') + 'Start_Of_Session_id'.length();
        integer endP = content.indexOf('End_Of_Session_Id');
        string sessionId = content.substring(startp,endP);
        return sessionId;
     }
}

Step 3 : listViewNewVersion.Html
<template>
   <lightning-card title="List View In New Version">
      <div class="clsCardBody">
         <!--################ list of Sbojects  #############-->          
         <div>
            <lightning-combobox
               name="sObjects"
               label="Select Object For Listview"
               value={objectApiName}
               options={sObjectOptions}
               onchange={handleChange} ></lightning-combobox>
         </div>
         <!--#############################-->          
         <div>&nbsp; &nbsp; &nbsp;&nbsp;</div>
         <!--################ Listview Start Here  #############-->          
         <article>
            <div class="slds-p-around_medium lgc-bg list_view_and_table_container"  id="myDIV">
               <lightning-tile label={objectName}  type="media" href="javascript:void(0);" class="list_view_container" >
                  <lightning-icon slot="media" icon-name={objectIcon} size="medium" class="icon_custom_class">
                  </lightning-icon>
                  <div class="slds-form-element">
                     <div class="slds-form-element__control">
                        <div class="slds-combobox_container testCustomCss">
                           <div class={dropdownTriggerClass} aria-expanded="false" aria-haspopup="listbox" role="combobox">
                              <div class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_right"
                                 role="none" onclick={handleClickExtend}>
                                 <span class="current_filter">
                                    {listViewName}
                                    <lightning-icon
                                       class="slds-m-left_x-small slds-button__icon slds-icon-utility-down slds-icon_container forceIcon"
                                       data-data-rendering-service-uid="232" data-aura-rendered-by="371:0"
                                       data-aura-class="forceIcon" icon-name="utility:down" size="x-small">
                                    </lightning-icon>
                                 </span>
                              </div>
                              <div  class="listViewPickerPanel deActive_ListView uiPanel--default uiPanel positioned south" 
                                 aria-hidden="true" tabindex='0'  onfocusout={handelFocusOut} style="outline:none;">
                                 <div id="listbox-id-1" class="slds-form-element slds-lookup forceVirtualAutocompleteMenu max_height"
                                    role="listbox" >
                                    <ul class="slds-listbox slds-listbox_vertical" role="presentation">
                                       <li role="presentation" class="slds-dropdown__header slds-text-heading--label forceVirtualAutocompleteMenuOption">
                                          <div>List Views</div>
                                       </li>
                                       <template for:each={listViewOptions} for:item="option">
                                          <li role="presentation" class="slds-listbox__item" key={option.value}>
                                             <div class="slds-media slds-listbox__option slds-listbox__option_plain slds-media_small"
                                                data-filter={option.value} onclick={getListViewValue}  
                                                >
                                                <span class="slds-media__figure slds-listbox__option-icon"
                                                   data-filter={option.value}>
                                                   <template if:true={option.show_option_icon}>
                                                      <lightning-icon icon-name="utility:check" size="xx-small" class="my-icon">
                                                      </lightning-icon>
                                                   </template>
                                                </span>
                                                <span class="slds-media__body" data-filter={option.value}>
                                                <span class="slds-truncate" 
                                                   data-filter={option.value}>{option.label}</span>
                                                </span>
                                             </div>
                                          </li>
                                       </template>
                                    </ul>
                                 </div>
                              </div>
                           </div>
                        </div>
                     </div>
                  </div>
               </lightning-tile>
            </div>
            <div class="table_cc">
               <!--################ Lightning Spinner start here #############-->          
               <template if:true={isLoading}>
                  <lightning-spinner alternative-text="spinner"></lightning-spinner>
               </template>
               <!--################ Lightning Spinner end here #############-->          
               <!--################ list view dataTable start here #############-->
               <lightning-datatable
                  key-field="id"
                  columns={lstviewCol}
                  data={storeListViewRecords}
                  show-row-number-column
                  >
               </lightning-datatable>
               <!--################ list view dataTable end here ############-->
               <template if:false={hasRecords}>
                  <div class="No_Record_Found_Css">No items to display</div>
               </template>
            </div>
         </article>
         <!--################ Listview End Here  #############-->          
      </div>
   </lightning-card>
</template>

Step 4 : listViewNewVersion.Js
   /* Author : Ravi Soni
      Date   : 16 Oct 2021
      Content: dynmic Listview In Lwc
   */
import {LightningElement,wire} from 'lwc'; import fetchListView from '@salesforce/apex/listViewNewVersionCtrl.fetchListView'; import getListviewRecords from '@salesforce/apex/listViewNewVersionCtrl.getListviewRecords'; import { getListInfoByName } from 'lightning/uiListsApi'; let lstLookupFilds = []; export default class ListViewNewVersion extends LightningElement { objectName = 'Accounts'; objectIcon = 'standard:account'; objectApiName = 'Account'; defaultListView; lstviewCol; storeListViewRecords; isLoading = true; hasRecords = false; listViewOptions = []; listViewName; developerName; /* ######## list of sObjects with icon ######### */ get sObjectOptions() { return [ { label: 'Accounts', value: 'Account', icon : 'standard:account' }, { label: 'Contacts', value: 'Contact' , icon : 'standard:contact'}, { label: 'Opportunities', value: 'Opportunity', icon : 'standard:opportunity' }, { label: 'Cases', value: 'Case', icon : 'standard:case' } ]; } /* ####### handle sObject records ####### */ handleChange(event) { this.isLoading = true; let value = event.detail.value; let sobjectOptions = this.sObjectOptions.find(data => data.value == value); this.objectApiName = value; this.objectName = sobjectOptions.label; this.objectIcon = sobjectOptions.icon; } /* fetch ListView Records based on objectApiName */ @wire(fetchListView, {objectApiName : '$objectApiName' }) ListView(value) { const { data, error } = value; if (data) { this.isLoading = true; let plistViewOptions = JSON.parse(JSON.stringify(data)); let lstOption = []; for (var i = 0; i < plistViewOptions.length; i++) { if( plistViewOptions[i].DeveloperName.toLowerCase().includes('recentlyviewed')){ this.defaultListView = plistViewOptions[i].Id; this.listViewName = plistViewOptions[i].Name; this.developerName = plistViewOptions[i].DeveloperName; } lstOption.push({ label: plistViewOptions[i].Name, value: plistViewOptions[i].Id, developerName : plistViewOptions[i].DeveloperName, show_option_icon: false }); if (this.defaultListView == plistViewOptions[i].Id) { lstOption[i].show_option_icon = true; } } this.listViewOptions = lstOption; } else if (error) { this.isLoading = false; console.log('error===> ' + JSON.stringify(error)) this.listViewOptions = []; } } /* fetch listview Columns */ @wire(getListInfoByName, { objectApiName: '$objectApiName', listViewApiName: '$developerName' })listInfo({ error, data }) { if (data) { lstLookupFilds = []; var columns = []; var result = data.displayColumns; for(var i=0; i<result.length; i++){ var fieldApi = result[i].fieldApiName; var fieldLabel = result[i].label; if( result[i].fieldApiName.includes('.')){ let splitData = result[i].fieldApiName.split('.'); var lookupApi = ''; for(var j=0; j<splitData.length; j++){ lookupApi += splitData[j]; } fieldApi = lookupApi; lstLookupFilds.push(result[i].fieldApiName); } columns.push({ label :fieldLabel, fieldName : fieldApi, type : 'text' }); } this.lstviewCol = columns; this.fetchListViewRecords(); } else if (error) { console.log('columns error==> ' + error); columns = undefined; } } /* fetch listview Records */ fetchListViewRecords(){ getListviewRecords({listviewId: this.defaultListView , objectApiName : this.objectApiName }).then(response=> { var result = response; var updateResult = []; result.forEach(function(record){ var tempRec = JSON.parse(JSON.stringify(record)); for(var fld in record){ if(typeof record[fld] == 'object'){ for(var j=0; j<lstLookupFilds.length; j++){ if(lstLookupFilds[j].includes('.')){ let splitFields = lstLookupFilds[j].split('.'); let keyField = splitFields[0]; if(fld == keyField){ var lookupApiName= splitFields.length > 2 ? splitFields[0]+splitFields[1] + splitFields[2] : splitFields[0]+splitFields[1]; var lookupvalue= splitFields.length > 2 ? record[fld][splitFields[1]][splitFields[2]] : record[fld][splitFields[1]]; tempRec[lookupApiName] = lookupvalue; } } } } } updateResult.push(tempRec); }); this.hasRecords = updateResult.length > 0 ? true:false; this.storeListViewRecords = updateResult; this.isLoading = false; }).catch(error => { this.storeListViewRecords = []; console.log('listView records error: '+JSON.stringify(error)); }); } /* listView expend collapse functionility*/ handleClickExtend(event) { let getElement = this.template.querySelector('.listViewPickerPanel'); if (getElement.classList.contains('deActive_ListView')){ getElement.setAttribute('aria-hidden', false); getElement.classList.remove('deActive_ListView'); getElement.classList.add('active_ListView'); this.template.querySelector('.listViewPickerPanel').focus(); } else { this.closeListViewHelper(); } } handelFocusOut(event) { let that = this; setTimeout(function(){ that.closeListViewHelper(); }, 300); } getListViewValue(event) { let listViewValue = event.target.dataset.filter; if (listViewValue != this.defaultListView) { this.isLoading = true; this.defaultListView = listViewValue; let getListViewRec = this.listViewOptions.find(data => data.value == listViewValue); this.listViewName = getListViewRec.label; this.developerName = getListViewRec.developerName; let self = this; this.listViewOptions.forEach(function(item){ item.show_option_icon = item.developerName == self.developerName ? true : false; }); } this.closeListViewHelper(); } closeListViewHelper(){ let getElement = this.template.querySelector('.listViewPickerPanel'); getElement.setAttribute('aria-hidden', true); getElement.classList.remove('active_ListView'); getElement.classList.add('deActive_ListView'); } }
Step 5 : listViewNewVersion.css
.lgc-bg {
	background-color: rgb(242, 242, 242);
}

.lgc-bg-inverse {
	background-color: rgb(22, 50, 92);
}

.label-hidden>label {
	display: none !important;
}

.icon_custom_class {
	margin-top: 5px;
}

.current_filter {
	color: rgb(8, 7, 7);
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	font-size: 1.125rem;
	font-weight: 700;
	line-height: 1.25;
	display: block;
	cursor: pointer;
}

.current_filter:hover {
	text-decoration: underline;
}

.custom_list_view {
	max-width: max-content;
}

.button_class {
	margin-left: 10px;
	margin-right: 10px;
}

.list_view_container {
	max-width: max-content;
}

.list_view_and_table_container {
	display: flex;
	align-items: center;
	justify-content: space-between;
}

.max_height {
	max-height: 409px;
}

.deActive_ListView {
	opacity: 0;
	display: none;
	z-index: 9001;
	position: absolute;
	left: 0px;
	top: 24px;
	visibility: hidden;
}

.active_ListView {
	opacity: 1;
	display: block;
	z-index: 9001;
	position: absolute;
	left: 0px;
	top: 24px;
	visibility: visible;
}

.my-icon {
	--sds-c-icon-color-foreground-default: rgb(0, 112, 210, 1);
}
.No_Record_Found_Css {
	text-align: center;
	margin-top: 200px;
}

.table_cc {
	background-color: rgb(250, 250, 249);
}
.clsCardBody{
	padding : 10px; 
}
Step 6 : listViewNewVersion.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
   <isExposed>true</isExposed>
    <targets>

        <target>lightning__AppPage</target>
        <target>lightning__HomePage</target>
        
    </targets>
</LightningComponentBundle>
Step 7 : For Output
Add this Component to Home page or Lightning App Page.
For Home Page => Click Setting Icon=> Edit Page => drag & drop Cmp and Save it.


Resources : 


Note : Please open this output video in new tab for better view.

Output : -





Post a Comment

4 Comments

  1. Nice work! Adding a test class for this would be perfect.. covering REST API apex code is giving me trouble lol

    ReplyDelete
  2. Illegal character(s) in message header ... CalloutException is occuring, will you please help?

    ReplyDelete
  3. Data is not coming
    illegal Character in message header value
    illegal conversion from list to Map
    Please help!

    ReplyDelete
  4. Hi Aditya,
    sorry for the delay, I reviewed my code and again checked. it's giving me the output. please make sure you copied well or you passed the write parameters.
    Thank You

    ReplyDelete

If you have any doubts please comment us

Ad Code

Responsive Advertisement