---
title: "Retrieving and displaying data from a RESTful API using Async in Knockout JS"  
description: "Retrieving and displaying data from a RESTful API involves several steps."  
author: "ICSM Computer"  
published: 2024-05-27  
updated: 2025-04-23  
canonical: https://www.mindstick.com/articles/335932/retrieving-and-displaying-data-from-a-restful-api-using-async-in-knockout-js  
category: "knockcout js"  
tags: ["javascript", "javascript framework", "knockout.js", "front-end development"]  
reading_time: 5 minutes  

---

# Retrieving and displaying data from a RESTful API using Async in Knockout JS

Retrieving and [displaying data](https://www.mindstick.com/forum/309/displaying-data-in-crystal-report-when-data-is-in-xml-file) from a [RESTful API](https://www.mindstick.com/forum/157904/what-is-a-restful-api-and-how-does-it-differ-from-other-types-of-apis) 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

1. **Choose the API and endpoint**: Identify the API you want to use and the specific endpoint from which you want to [retrieve data](https://answers.mindstick.com/qa/102391/how-does-a-computer-hard-drive-store-and-retrieve-data). Ensure you have any necessary API keys or authentication tokens.
2. **Install required libraries**: For Python, you'll typically use the **requests** library to make [HTTP requests](https://www.mindstick.com/forum/23192/using-java-dot-net-urlconnection-to-fire-and-handle-http-requests). If not already installed, you can install it using **pip**.
3. **Make the [HTTP request](https://www.mindstick.com/forum/161390/what-is-http-service-in-angularjs-and-how-do-you-make-an-http-request)**: Use the **requests** library to send a GET request to the API endpoint.
4. **Handle the response**: Check the response status code to ensure the request was successful. Parse the JSON data from the response.
5. **Display the data**: Extract and display the [relevant information](https://answers.mindstick.com/qa/105781/how-to-interpret-financial-news-and-filter-relevant-information-for-investing) 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.

```javascript
<!-- 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.

```javascript
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](https://www.mindstick.com/forum/161355/how-does-data-binding-work-in-wpf) syntax to bind the data from the ViewModel to [HTML elements](https://answers.mindstick.com/qa/93760/how-to-find-the-html-elements-by-using-javascript).

```html
<!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](https://www.mindstick.com/forum/160127/describe-the-options-for-caching-retrieved-data-in-a-dot-net-core-api).

```javascript
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](https://www.mindstick.com/forum/160903/how-to-handle-errors-using-try-catch-block-in-sql-server) appropriately and customize the code according to your specific API and requirements.

**Thanks for reading.**

---

Original Source: https://www.mindstick.com/articles/335932/retrieving-and-displaying-data-from-a-restful-api-using-async-in-knockout-js

Copyright © MindStick Software Pvt. Ltd. This Markdown version is provided for developers, AI systems, and offline reading.
