3. Using APIs
This step takes our static components and populates them with data from the GitHub GraphQL API – loading states and all. We’ll be displaying Carbon repository information in a data table.
Preview
The GitHub REST API is very well documented, we’ll use it to fetch Carbon-related data for this Carbon tutorial.
To do so, we’ll be using Octokit Core, a client that makes it easy to interact with GitHub’s APIs.
A preview of what you will build (see repositories page):
Fork, clone and branch
This tutorial has an accompanying GitHub repository called carbon-tutorial-web-components that we’ll use as a starting point for each step. If you haven’t forked and cloned that repository yet, and haven’t added the upstream remote, go ahead and do so by following the [step 1 instructions](previous step.
Branch
With your repository all set up, let’s check out the branch for this tutorial step’s starting point.
git fetch upstreamgit checkout -b step-3 upstream/step-3
Build and start app
Install the app’s dependencies and build the app:
pnpm i
Then, start the app:
pnpm dev
You should see something similar to where the previous step left off. Stop your app with
CTRL-C
Install dependencies
We’ll need to install
@octokit/core
CTRL-C
pnpm add @octokit/core
Then, start the app again. If your app’s currently running, you’ll need to restart it.
pnpm dev
Fetch and render data
Imports
Add the following import Octokit into
repos.js
import { Octokit } from '@octokit/core';const octokitClient = new Octokit({});
API Request
Next, we’ll assemble our GitHub API request to fetch a list of repositories that belong to the
carbon-design-system
First empty the data array in
repos.js
let data = [];
Then add the function
fetchData
const fetchData = async () => {const res = await octokitClient.request('GET /orgs/{org}/repos', {org: 'carbon-design-system',per_page: 75,sort: 'updated',direction: 'desc',});if (res.status === 200) {
Rendering the data
If you have the application running then the only change you see is an empty table. Let’s fix that next.
In
repositories.html
<cds-table>
<cds-table-skeleton></cds-table-skeleton>
Then move the
<cds-table>
template--table
<template id="template--table"><cds-table expandable><cds-table-header-title slot="title">Carbon Repositories</cds-table-header-title><cds-table-header-description slot="description">A collection of public Carbon repositories.</cds-table-header-description><cds-table-head>
With the application running the repositories page now shows the skeleton table. Skeleton components are used in the Carbon Design System to information is still being loaded. For further details on Carbon loading patterns.
Returning to
repos.js
updateTable
updateTable();
and replace it with the new function called
replaceSkeleton
const replaceSkeleton = () => {const tableSkeleton = document.querySelector('cds-table-skeleton');const tableTemplate = document.querySelector('template#template--table');if (tableSkeleton && tableTemplate) {tableSkeleton.replaceWith(tableTemplate.content.cloneNode(true));// update table rowsupdateTable();}
This function locates the
template--table
updateTable
We are now ready to display the data by adjusting the function
fetchData
replaceSkeleton
// replace table here// replaceSkeleton();
to leave:
// replace table herereplaceSkeleton();
At this point when you refresh the
repositories
link
At the top of
repos.js
cds-link
import '@carbon/web-components/es/components/link/index';
Find
links: 'link'
fetchData
links: { url: row.html_url, homepage: row.homepage },
In our
updateTable
keyEl.innerHTML = row[key];
with
if (key === 'links') {keyEl.innerHTML = `<ul class="link-list"><li><cds-link href="${row[key].url}">GitHub</cds-link></li><li><cds-link href="${row[key].homepage}">Homepage</cds-link></li></ul>`;
Now it we could have added the HTML for the links in
repositories.html
Open
styles.scss
.link-list {display: flex;list-style: none;padding: 0;}.link-list li:not(:last-child) {padding-inline-end: $spacing-02;
Pagination
The data rendered in our table produces quite a tall page which grows with each new Carbon repository. To complete our repositories page we will add pagination to the table.
In
repos.js
import '@carbon/web-components/es/components/pagination/index';
Now, as part of the
template--table
repositories.html
<cds-table>
<cds-paginationbackward-text="Previous page"forward-text="Next page"itemsPerPageText="Items per page"><cds-select-item value="10">10</cds-select-item><cds-select-item value="20">20</cds-select-item><cds-select-item value="30">30</cds-select-item><cds-select-item value="40">40</cds-select-item><cds-select-item value="50">50</cds-select-item>
If you scroll to the bottom of the
repositories
Back in
repos.js
let data = [];let pageSize = 10;let firstRowIndex = 0;
Next we need to add some script to handle events raised by the pagination component and update it with the values defined for
pageSize
firstRowIndex
const handlePageChangeCurrent = ({ detail }) => {firstRowIndex = (detail.page - 1) * detail.pageSize;updateTable();};const handlePageSizeChange = ({ detail }) => {pageSize = detail.pageSize;updateTable();};
Add a call to
updatePagination
replaceSkeleton
updateTable
// update table rowsupdateTable();// update paginationupdatePagination();
When triggered the handlers update
firstRowIndex
pageSize
updateTable
updateTable
Currently, we iterate over the data as follows:
// iterate over data and render rowsdata.forEach((row) => {// rows update here});
Change this introducing a filter before the
forEach
// iterate over data and render rowsdata.filter((v, i) => i >= firstRowIndex && i < firstRowIndex + pageSize).forEach((row) => {// rows update here});
Refreshing the repositories page should now show just ten rows. Try changing the page size and the current page number, this should result in new data being loaded.
That does it! Your data table should fetch GitHub data on first render. You can expand each row to see the repository’s description. You can modify the pagination items per page and cycle through pages or jump to a specific page of repositories.
Push to GitHub
That is it you are done. Just one more push to save your completion of step 3.
Git commit and push
First, stage and commit all of your changes:
git add --all && git commit -m "feat(tutorial): complete step 3"
Then, push to your repository:
git push -u origin step-3