Display Data Using Base Components

A common way to display data is to use datatables. LWC provides the lightning-datatable base component for displaying large amounts of data. lightning-datatable supports a wide range of column types that are ideal for displaying record data, such as currency, date, email, and even a dropdown menu for row-level actions. You can also load more data by implementing pagination or infinite scrolling on the datatable.

To display your records using lightning-datatable, set key-field="Id" and specify the data and column properties.

1<!-- datatableWithGraphql.html -->
2<template>
3  <template lwc:if={accounts}>
4    <lightning-datatable key-field="Id" data={accounts} columns={columns} hide-checkbox-column>
5    </lightning-datatable>
6  </template>
7  <template lwc:elseif={errors}>
8    <!-- Display errors -->
9  </template>
10</template>

In your JavaScript, create your columns and define your data using key-value pairs when it’s returned by the GraphQL wire adapter.

1// datatableWithGraphql.js
2import { LightningElement, wire } from "lwc";
3import { gql, graphql } from "lightning/graphql";
4
5const columns = [
6  { label: "Name", fieldName: "Name" },
7  { label: "Phone", fieldName: "Phone", type: "phone" },
8  { label: "Website", fieldName: "Website", type: "url" },
9  { label: "Annual Revenue", fieldName: "AnnualRevenue", type: "currency" },
10];
11
12export default class DatatableWithGraphql extends LightningElement {
13  // Array of accounts to display
14  accounts = undefined;
15  // Errors from the wire adapter
16  errors = undefined;
17  // Columns for datatable
18  columns = columns;
19
20  @wire(graphql, {
21    query: gql`
22      query AccountWithName {
23        uiapi {
24          query {
25            Account {
26              edges {
27                node {
28                  Id
29                  Name {
30                    value
31                  }
32                  Phone {
33                    value
34                  }
35                  Website {
36                    value
37                  }
38                  AnnualRevenue {
39                    displayValue
40                  }
41                }
42              }
43            }
44          }
45        }
46      }
47    `,
48  })
49  gqlQuery({ data, errors }) {
50    if (data) {
51      this.accounts = data.uiapi.query.Account.edges.map((edge) => ({
52        Id: edge.node.Id,
53        Name: edge.node.Name.value,
54        Phone: edge.node.Phone.value,
55        Website: edge.node.Website.value,
56        AnnualRevenue: edge.node.AnnualRevenue.displayValue,
57      }));
58    }
59    this.errors = errors;
60  }
61}

Add pagination to the datatable with a refresh button and a next button. The refresh button takes users back to the start of the results. The next button becomes disabled when the end of the results is reached.

Backward pagination using last and before isn’t currently supported.

Note

1<!-- datatableWithGraphqlPagination -->
2<template>
3  <lightning-button-icon icon-name="utility:skip_back" onclick="{resetPagingCursor}"
4    ><label>Reset Pagination</label></lightning-button-icon
5  >
6  <lightning-button-icon
7    disabled="{isFinalPage}"
8    class="next"
9    icon-name="utility:chevronright"
10    onclick="{getNextPage}"
11    ><label>Next</label></lightning-button-icon
12  >
13  <p>Total records found: {totalCount}</p>
14  <p>Page {currentPage} of {totalPages}</p>
15
16  <template lwc:if="{accounts}">
17    <lightning-datatable key-field="Id" data="{accounts}" columns="{columns}" hide-checkbox-column>
18    </lightning-datatable>
19  </template>
20  <template lwc:elseif="{errors}">
21    <!-- Display errors -->
22  </template>
23</template>

Building on the previous lightning-datatable example, query the pageInfo object for cursor and pagination information.

1// datatableWithGraphqlPagination.js
2import { LightningElement, wire } from "lwc";
3import { gql, graphql } from "lightning/graphql";
4
5const columns = [
6  { label: "Name", fieldName: "Name" },
7  { label: "Phone", fieldName: "Phone", type: "phone" },
8  { label: "Website", fieldName: "Website", type: "url" },
9  { label: "Annual Revenue", fieldName: "AnnualRevenue", type: "currency" },
10];
11
12export default class DatatableWithGraphqlPagination extends LightningElement {
13  // Array of accounts to display
14  accounts = undefined;
15  // Errors from the wire adapter
16  errors = undefined;
17  // Columns for datatable
18  columns = columns;
19
20  // Cursor of the last returned record
21  lastCursor = null;
22
23  // Cursor for the next page
24  endCursor = null;
25
26  // Checks if the page is the last page
27  // Disables the next page button if true
28  isFinalPage = false;
29
30  // Total number of query results
31  totalCount = null;
32  page = 1;
33  totalPages = 1;
34  @wire(graphql, {
35    query: "$accountQuery",
36    variables: "$variables",
37  })
38  gqlQuery({ data, errors }) {
39    if (data) {
40      this.accounts = data.uiapi.query.Account.edges.map((edge) => ({
41        Id: edge.node.Id,
42        Name: edge.node.Name.value,
43        Phone: edge.node.Phone.value,
44        Website: edge.node.Website.value,
45        AnnualRevenue: edge.node.AnnualRevenue.displayValue,
46      }));
47      this.isFinalPage = !data.uiapi.query.Account.pageInfo.hasNextPage;
48      this.endCursor = data.uiapi.query.Account.pageInfo.endCursor;
49      this.totalCount = data.uiapi.query.Account.totalCount;
50      this.totalPages = Math.ceil(this.totalCount / 10);
51    }
52    this.errors = errors;
53  }
54
55  // Define the GraphQL query
56  get accountQuery() {
57    return gql`
58      query AccountWithName($after: String) {
59        uiapi {
60          query {
61            Account(after: $after) {
62              edges {
63                node {
64                  Id
65                  Name {
66                    value
67                  }
68                  Phone {
69                    value
70                  }
71                  Website {
72                    value
73                  }
74                  AnnualRevenue {
75                    displayValue
76                  }
77                }
78              }
79              pageInfo {
80                endCursor
81                hasNextPage
82                hasPreviousPage
83              }
84              totalCount
85            }
86          }
87        }
88      }
89    `;
90  }
91
92  // Define variables for the GraphQL query
93  get variables() {
94    return {
95      after: this.lastCursor,
96    };
97  }
98
99  get currentPage() {
100    return this.totalCount === 0 ? 0 : this.page;
101  }
102
103  // Click handler for the reset button
104  resetPagingCursor(event) {
105    this.lastCursor = null;
106    this.page = 1;
107  }
108
109  // Click handler for the next page button
110  getNextPage(event) {
111    if (!this.isFinalPage) {
112      this.lastCursor = this.endCursor;
113      this.page++;
114    }
115  }
116}