About cookies on this site Our websites require some cookies to function properly (required). In addition, other cookies may be used with your consent to analyze site usage, improve the user experience and for advertising. For more information, please review your options. By visiting our website, you agree to our processing of information as described in IBM’sprivacy statement. To provide a smooth navigation, your cookie preferences will be shared across the IBM web domains listed here.
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
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.
repos.jsimport { 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
repos.jslet data = [];
Then add the function fetchData
calling it immediately afterwards.
repos.jsconst 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.
repositories.html<cds-table-skeleton></cds-table-skeleton>
Then move the <cds-table>
into a template called template--table
at the
bottom of the file.
repositories.html<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
repos.jsupdateTable();
and replace it with the new function called replaceSkeleton
below:
repos.jsconst 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
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
.
repos.js// replace table here// replaceSkeleton();
to leave:
repos.js// replace table herereplaceSkeleton();
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.
repos.jsimport '@carbon/web-components/es/components/link/index';
Find links: 'link'
in the fetchData
function and replace it with:
repos.jslinks: { url: row.html_url, homepage: row.homepage },
In our updateTable
function we need to do something different for the links
key. Replace
repos.jskeyEl.innerHTML = row[key];
with
repos.jsif (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.
style.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 the pagination component.
repos.jsimport '@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.
repositories.html<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
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.
repos.jslet 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
.
repos.jsconst 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
repos.js// update table rowsupdateTable();// update paginationupdatePagination();
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:
repos.js// iterate over data and render rowsdata.forEach((row) => {// rows update here});
Change this introducing a filter before the forEach
.
repos.js// 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