Blog

Display Records in LWC using SAQL and Rest API

In this blog we are about to see how data can be retrieved by SAQL Query and displayed in UI using LWC Component.

Display Records in LWC
  1. Salesforce Analytic Query Language(SAQL), a natively developed query language to navigate data.
  2. Create Data Set using data flow.
  3. We use SAQL (Salesforce Analytics Query Language) to access data in Analytics Cloud datasets.
  4. Analytics Cloud uses SAQL behind the scenes in lenses, dashboards, and explorers to gather data for visualizations.
  5. We use SAQL queries for complex requirements.

SAQL Query in Lens :

Display Records in LWC

In above SAQL query we get all the Opportunity records grouped by Stage Name.

Get Data From SAQL query Using LWC

Apex Code :

  1. Get Auth token and Http Response. We can get auth token and response from the Apex class and pass to the Lwc Js.

Constant variable Declaration

public class Constants {
    public static String POST = 'POST';
    public static String PATCH = 'PATCH';
    public static String GET = 'GET';
    public static String AUTHORIZATION =
 
'Authorization';
    public static String BEARER = 'Bearer ';
    public static String BASIC = 'Basic ';
}


Http response Declaration

public class RestAPIUtil {
    public static HttpResponse getHTTP(String endPoint,
    Map<String,String> headers){
       HttpRequest request = new HttpRequest();
       HttpResponse response = new HttpResponse();
       Http http = new Http();
       request.setMethod(Constants.GET);
       request.setEndpoint(endpoint);
    for(String header : headers.keySet()){
      request.setHeader(header,headers.get(header));
}
try {
     response = http.send(request);
     return response;
} catch(System.CalloutException e) {
    throw new GateWayException('Error Occured in
    Http call out',e);
}
} public static HttpResponse postHTTP(String endpoint,
     Map<String,String> headers){
     HttpRequest request = new HttpRequest();
     HttpResponse response = new HttpResponse();
     Http http = new Http();request.setMethod(Constants.POST);
     request.setEndpoint(endpoint);
for(String header : headers.keySet()){
     request.setHeader(header,headers.get(header));
}try {
     response = http.send(request);
     return response;
} catch(System.CalloutException e) {
     throw new GateWayException('Error Occured in
     Http call out',e);
   }
} 
public class GateWayException extends Exception {}
}

Apex class for Get Access token And CurrentVersionId

public class ApiCallForSaql {
    @AuraEnabled(cacheable=true)
  public static string CreateToken()
  {
    Map<String, String> headers = new Map<String,
    String>();
    String url =
    'https://innovalleyworks6-dev-ed.my.salesforce.com/services/o
    auth2/token?grant_type=password&client_id="Client Id"&client_secret="Your Client Secret"&username = 'Your Username'&
    password='Your Password';
    headers = new Map<String, String>();
    headers.put('Content-Type',
   'application/json');
   httpresponse res = RestAPIUtil.postHTTP(url,
headers);
 
   AccessToken wrpToken = new AccessToken();
   wrpToken = (AccessToken)
   JSON.deserialize(res.getBody(), AccessToken.class);
   return wrpToken.access_token;
} @
AuraEnabled
public static Map<string, String>
   getSessionAndVersions()
   { 
   Map<string, String> resultMap = new Map<String,
   String>();
   String token = CreateToken();
   resultMap.put('SESION', token);
   Map<String, String> headers = new Map<String,
   String>();
   String url =
   'https://innovalleyworks6-dev-     ed.my.salesforce.com/services/data/v53.0/wave/datasets/0Fb5j000000PYF4CAO';
   headers = new Map<String, String>();
   headers.put('Content-Type',
  'application/json');
   headers.put('Authorization', 'Bearer ' + token);
   httpresponse response =
   RestAPIUtil.getHTTP(url, headers);
   resultMap.put('DATASET', response.getBody());
   return resultMap;
} public class AccessToken{
  public String access_token{get;set;}
  }
}

LWC JS :

We can get the Data from SAQL Query directly from LWC Js Using the Auth token and response received from Apex.

import { LightningElement } from 'lwc';
//End point from CustomLabel(enter your endpoint URL)
import endpoint from '@salesforce/label/c.endpoint';Import
getSessionAndVersions
from'@salesforce/apex/ApiCallForSaql.getSessionAndVersions';
export default class GetSaqlQueryData extends LightningElement {
    error;
    endError;
    responseData = [];
    connectedCallback() {
    this.logoUrl = endpoint;
    this.dataLoad();
 
} 
dataLoad() {
    getSessionAndVersions()
    .then(result => {
    this.responseValue = result.DATASET;this.parseValue =           JSON.parse(this.responseValue);
    console.log('this.parseValue==',this.parseValue);
    this.token = result.SESION;
    console.log('this.token ==',this.token);
    let AuthToken ="Bearer "+this.token;
    console.log('AuthToken ==',AuthToken);
    let req = new XMLHttpRequest();
    req.open('POST',this.endPoint , true);
    let queryStr ="q =load
    \"0Fb5j000000PYF4CAO/"+this.parseValue.currentVersionId+"\";
    q = group q by 'StageName';
    q = foreach q generate 'StageName' as 'StageName', count() as 'count',
    sum('Amount') as 'sum_Amount', max('Amount') as 'max_Amount',
    min('Amount') as 'min_Amount';
    q = order q by 'StageName' asc;q = limit q 2000;"
    let data = {query: queryStr}
    let fileBody= JSON.stringify({"query": data});
    const endPoints = this.logoUrl;
       fetch(
          endPoints,
           {
            method: "POST",
               headers: {
                 "Authorization": AuthToken,
                 "Content-Type" : 'application/json',
                 "Accept" : 'application/json'
                 },
         body: JSON.stringify(data)
         }
        ).then(response => response.json())
        .then(datas =>{
        console.log('datas==',datas);
       this.responseData = datas.results.records;
    });
})
.catch(error => {
    this.error = error;
    this.responseValue = undefined;
    this.isLoading = false;
   });}
}


UI Code

<template>
   <template if:true={responseData}>
      <div class="slds-box slds-theme_shade table-scroll"
         style="background:#FFFFFF !important;margin:10px ;padding:0px">
         <table id="example" class="table table-striped table-bordered
            slds-table slds-table_bordered slds-table_cell-buffer" >
            <thead>
               <tr>
                  <th class="backgroundHead" scope="col" rowspan='2'>
                     <div class="slds-truncate
                        slds-text-title_bold"title="Accounts">StageName</div>
                  </th>
                  <th class="backgroundHead" scope="col" rowspan='2'>
                     <div class="slds-truncate slds-text-title_bold"
                        title="YTD Revenue">Count</div>
                  </th>
                  <th class="backgroundHead" scope="col" rowspan='2'>
                     <div class="slds-truncate slds-text-title_bold" title="%
                        Sucessful">Max Ammount</div>
                  </th>
                  <th class="backgroundHead" scope="col" rowspan='2'>
                     <div class="slds-truncate slds-text-title_bold"
                        title="Total">Min Ammount</div>
                  </th>
                  <th class="backgroundHead" scope="col" colspan='2' >
                     <div class="slds-truncate slds-text-title_bold"
                        title="YTD Revenue">Sum Ammount</div>
                  </th>
               </tr>
            </thead>
            <tbody>
               <template for:each={responseData} for:item="gridData">
                  <tr key={gridData.StageName}>
                     <td data-label="accName" class="" scope="col" >
                        <div class="slds-truncate" title="Start Week" >
                           <p><lightning-formatted-textvalue={gridData.StageName}>
                              </lightning-formatted-text>
                           </p>
                        </div>
                     </td>
                     <td data-label="ydtRevenue" class="" scope="col" >
                        <div class="slds-truncate" title="Start Week" >
                           <p class = "alignright">
                              <lightning-formatted-number
                                 value={gridData.count}></lightning-formatted-number>
                           </p>
                        </div>
                     </td>
                     <td data-label="ydtsales" class="" scope="col" >
                        <div class="slds-truncate" title="YTD Split Revenue">
                           <p class = "alignright">
                              <lightning-formatted-number
                                 value={gridData.max_Amount}></lightning-formatted-number>
                           </p>
                        </div>
                     </td>
                     <td data-label="totalSumValue" class="" scope="col" >
                        <div class="slds-truncate" title="YTD Split Revenue">
                           <p class = "alignright">
                              <lightning-formatted-number
                                 value={gridData.min_Amount} ></lightning-formatted-number>
                           </p>
                        </div>
                     </td>
                     <td data-label="domesticRevene" class="" scope="col">
                        <div class="slds-truncate" title="YTD Domestic
                           Revenue">
                           <p class = "alignright">
                              <lightning-formatted-number
                                 value={gridData.sum_Amount} format-style="currency" currency-code="GBP"maximum-fraction-digits="0"
                                 minimum-fraction-digits="0"></lightning-formatted-number>
                           </p>
                        </div>
                     </td>
                  </tr>
               </template>
            </tbody>
         </table>
      </div>
   </template>
</template>

Output :

Display Records in LWC