Skip to main contentCarbon Design System

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 upstream
git 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
and let’s get everything installed.

Install dependencies

We’ll need to install

@octokit/core
, a package that allows us to query GitHub APIs easily. Stop your development server with
CTRL-C
and install the octokit dependency with:

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
and create a new instance of Octokit.

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
GitHub organization.

First empty the data array in

repos.js

let data = [];

Then add the function

fetchData
calling it immediately afterwards.

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
just above the
<cds-table>
add a table skeleton.

<cds-table-skeleton></cds-table-skeleton>

Then move the

<cds-table>
into a template called
template--table
at the bottom of the file.

<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
we will makes use of the fetched data to replace the skeleton table. Find the current call to
updateTable

updateTable();

and replace it with the new function called

replaceSkeleton
below:

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 rows
updateTable();
}

This function locates the

template--table
and replaces the skeleton with it. It then makes a call to
updateTable
to add the rows.

We are now ready to display the data by adjusting the function

fetchData
by ucommenting the call to
replaceSkeleton
.

// replace table here
// replaceSkeleton();

to leave:

// replace table here
replaceSkeleton();

At this point when you refresh the

repositories
page the table skeleton is briefly shown before the table is populated with data from github. The link column however just shows
link
we will fix that next.

At the top of

repos.js
import the
cds-link
component.

import '@carbon/web-components/es/components/link/index';

Find

links: 'link'
in the
fetchData
function and replace it with:

links: { url: row.html_url, homepage: row.homepage },

In our

updateTable
function we need to do something different for the links key. Replace

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
but this serves to demonstrate that as with standard HTML tags it is possible to simply insert Carbon Web Components as innerHTML using a string. Just a little bit of CSS is needed to present this as per our tutorial design.

Open

styles.scss
and add the following.

.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 the pagination component.

import '@carbon/web-components/es/components/pagination/index';

Now, as part of the

template--table
template we can add the pagination to
repositories.html
after the closing
<cds-table>
tag.

<cds-pagination
backward-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>

Note: The

Pagination
component isn’t inherently connected in any way to the
DataTable
- we need to tell it what to do when a change occurs using the
onChange
prop. This includes both page size changes and displaying different rows.

Note: Like the other Carbon Web Components components,

Pagination
component examples can be found in Storybook by browsing the story and knobs.

If you scroll to the bottom of the

repositories
page in the browser you should see the pagination component rendered.

Back in

repos.js
next to the declaration of our data array add two further variables to work with the pagination component. Where we declare the data variable, add variables for page size and row index.

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
and
firstRowIndex
.

const handlePageChangeCurrent = ({ detail }) => {
firstRowIndex = (detail.page - 1) * detail.pageSize;
updateTable();
};
const handlePageSizeChange = ({ detail }) => {
pageSize = detail.pageSize;
updateTable();
};

Add a call to

updatePagination
in
replaceSkeleton
just after the call to
updateTable

// update table rows
updateTable();
// update pagination
updatePagination();

When triggered the handlers update

firstRowIndex
and
pageSize
before calling
updateTable
which re-renders our table rows. Before it all works we need to make a change to
updateTable
to render just the rows on the current page.

Currently, we iterate over the data as follows:

// iterate over data and render rows
data.forEach((row) => {
// rows update here
});

Change this introducing a filter before the

forEach
.

// iterate over data and render rows
data
.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

Note: If your Git remote protocol is HTTPS instead of SSH, you may be prompted to authenticate with GitHub when you push changes. If your GitHub account has two-factor authentication enabled, we recommend that you follow these instructions to create a personal access token for the command line. That lets you use your token instead of password when performing Git operations over HTTPS.