Retrieving and displaying data from a RESTful API involves several steps. Here, I'll outline the general process and provide a Python code example using the requests library to interact with a RESTful API and display the data.
Steps to Retrieve and Display Data from a RESTful API
- Choose the API and endpoint: Identify the API you want to use and the specific endpoint from which you want to retrieve data. Ensure you have any necessary API keys or authentication tokens.
- Install required libraries: For Python, you'll typically use the requests library to make HTTP requests. If not already installed, you can install it using pip.
- Make the HTTP request: Use the requests library to send a GET request to the API endpoint.
- Handle the response: Check the response status code to ensure the request was successful. Parse the JSON data from the response.
- Display the data: Extract and display the relevant information from the JSON data.
Step 1: Include Knockout.js Library
Make sure you have included the Knockout.js library in your HTML file. You can either download it and host it locally or include it from a CDN.
<!-- Link to Bootstrap CSS for styling -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<!-- Link to Knockout.js library for MVVM pattern support -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.min.js"
integrity="sha512-vs7+jbztHoMto5Yd/yinM4/y2DOkPLt0fATcN+j+G4ANY2z4faIzZIOMkpBmWdcxt+596FemCh9M18NUJTZwvw=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- Link to jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
Step 2: Define ViewModel
Create a ViewModel in JavaScript. This ViewModel will hold the data retrieved from the API and bind it to the HTML.
class AppViewModel {
constructor() {
var self = this;
self.response = ko.observable({});
self.currentPage = ko.observable(0);
self.totalPages = ko.observable(0);
self.pagination = ko.observable({});
self.isLoading = ko.observable(false);
self.error = ko.observable(null);
self.fetchData = async function (url = '') {
self.isLoading(true);
self.error('');
};
}
}
// Apply bindings
ko.applyBindings(new AppViewModel());
Step 3: Bind Data to HTML
Use Knockout data binding syntax to bind the data from the ViewModel to HTML elements.
<!doctype html>
<html lang="en">
<head>
<!-- Meta tags for character set and viewport configuration -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Title of the webpage -->
<title>Bootstrap demo</title>
<!-- Link to Bootstrap CSS for styling -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<!-- Link to Knockout.js library for MVVM pattern support -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.min.js"
integrity="sha512-vs7+jbztHoMto5Yd/yinM4/y2DOkPLt0fATcN+j+G4ANY2z4faIzZIOMkpBmWdcxt+596FemCh9M18NUJTZwvw=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- Link to jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<!-- Main container for the content -->
<div class="container my-3">
<!-- Header for the section -->
<h2>Data from Server async</h2>
<!-- Button to fetch data -->
<button data-bind="click: fetchData('')" class="btn btn-secondary">Fetch Data</button>
<hr />
<div id="app">
<!-- Display loading state -->
<div data-bind="visible: isLoading">
<div class="d-flex justify-content-center fw-semibold fs-5 align-items-center">
<span class="me-2">Loading...</span>
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
</div>
<!-- Display error message if any -->
<div class="d-flex justify-content-center fw-semibold fs-5 align-items-center"
data-bind="visible: error, text: error" style="color: red;"></div>
<div class="my-3 d-flex justify-content-end align-items-baseline">
<span class="fw-semibold me-3" data-bind="with: { pages : pagination()}">
<span data-bind="text: pages.current_page"></span>
<span class="mx-1">of</span>
<span class="" data-bind="text: pages.total_pages"></span>
</span>
<ul class="pagination " data-bind="with: { pages : pagination(), prevUrl: pagination().prev_url, nextUrl: pagination().next_url, currentPage: pagination().current_page }">
<li class="page-item" data-bind="css: { 'disabled': !(currentPage > 1) }">
<a class="page-link" href="#"
data-bind="click: function() { $root.fetchData(''); }">
First
</a>
</li>
<li class="page-item" data-bind="css: { 'disabled': !(currentPage > 1) }">
<a class="page-link" href="#"
data-bind="click: function() { $root.fetchData(prevUrl); },
enable: (currentPage > 1)">
Previous
</a>
</li>
<li class="page-item active"><a class="page-link" href="#" data-bind="text: currentPage"></a></li>
<li class="page-item" data-bind="css: { 'disabled': !(currentPage < pages.total_pages) }">
<a class="page-link" href="#"
data-bind="click: function() { $root.fetchData(nextUrl); }">
Next
</a>
</li>
<li class="page-item" data-bind="css: { 'disabled': !(currentPage < pages.total_pages) }">
<a class="page-link" href="#"
data-bind="click: function() { $root.fetchData('https://api.artic.edu/api/v1/artworks?page='+pages.total_pages); }">
Last
</a>
</li>
</ul>
</div>
<!-- Display data if available -->
<div class="row g-3 row-cols-1 row-cols-md-2 row-cols-lg-3 row-cols-xl-4"
data-bind="visible: !isLoading(), foreach: response().data">
<!-- Column for each item -->
<div class="col">
<!-- Card to display item details -->
<div class="card ">
<img data-bind="if: (image_id || thumbnail), attr: {
src: 'https://www.artic.edu/iiif/2/' + image_id + '/full/400,/0/default.jpg',
alt: thumbnail ? thumbnail.alt_text : ''
}" class="card-img-top" height="250">
<div class="card-body">
<!-- Card title bound to item's title -->
<h5 class="card-title text-capitalize" data-bind="text: title"></h5>
<!-- Card text bound to item's body -->
<!-- <p class="card-text" data-bind="text: body"></p> -->
</div>
<div class="card-footer border-0 pt-0">
<!-- Footer with item id and a link -->
<p class="m-0 d-flex justify-content-between">
<!-- Item id displayed -->
<span class="fs-5 fw-bold" data-bind="text: id"></span>
<!-- Link to comments page for the item -->
<a data-bind="attr: { 'data-link': api_link }">
<!-- SVG icon inside the link -->
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor"
class="bi bi-arrow-right-circle-fill" viewBox="0 0 16 16">
<path
d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0M4.5 7.5a.5.5 0 0 0 0 1h5.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3a.5.5 0 0 0 0-.708l-3-3a.5.5 0 1 0-.708.708L10.293 7.5z" />
</svg>
</a>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Link to external JavaScript file -->
<script src="app.js"></script>
</body>
</html>
Step 4: Make AJAX Request to API
Inside the fetchData function of your ViewModel, use AJAX (e.g., jQuery's $.ajax) to make a GET request to the RESTful API endpoint and update the artworks observable with the retrieved data.
self.fetchData = async function (url = '') {
self.isLoading(true);
self.error('');
let _url = url || 'https://api.artic.edu/api/v1/artworks'; // Default URL
try {
// Simulate an asynchronous API call using fetch
let response = await fetch(_url);
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
let result = await response.json();
// console.log(result);
self.response(result); // Update the observable array with the fetched data
// Extract pagination data from the response and update observables accordingly
if (result.pagination) {
self.pagination(result.pagination);
}
} catch (err) {
self.error(err.message);
} finally {
self.isLoading(false);
}
};
Conclusion
This example demonstrates how to use Knockout.js to retrieve data from a RESTful API and bind it to HTML elements. Make sure to handle errors appropriately and customize the code according to your specific API and requirements.
Thanks for reading.
Leave Comment