softare development

How to Use JavaScript Fetch API to Get Real-time Data

JavaScript is a versatile programming language that powers the dynamic nature of the web. With the introduction of the Fetch API, JavaScript developers gained a powerful tool for making network requests and interacting with servers.

The Fetch API provides a modern, streamlined alternative to the traditional XMLHttpRequest (XHR) approach. In this tutorial, we will explore the Fetch API in detail, its core features, and how it simplifies asynchronous data fetching in JavaScript applications. We will also create a GET request using the Fetch API by consuming the JSON cat placeholder API as our example endpoint.

What is Fetch API

The Fetch API is a built-in JavaScript interface that enables fetching resources asynchronously across the network. It provides a simplified, promise-based syntax for making HTTP requests, allowing developers to send and receive data from servers with ease. The Fetch API supports a wide range of data formats, including JSON, text, blobs, and more.

How to Make a Fetch Request

Using the Fetch API is straightforward. To initiate a basic fetch request, we create a new instance of the fetch() function and pass in the URL of the resource we want to fetch. The fetch() function returns a Promise that resolves to the Response object containing the server’s response.

We can then use the Response object’s methods to handle the retrieved data. For example, we can call response.json() to extract JSON data, response.text() to get plain text, or response.blob() to retrieve binary data. These methods also return Promises, allowing us to chain them together or use async/await syntax for cleaner code.

Now, back to our example. What we want to do is create a simple HTML page and using just a bit of Bootstrap. We will show the Bootstrap spinner for the waiting period.

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
    <title></title>
  </head>
  <body>
    <div class="container">
      <center>
      <div class="spinner-border" role="status" id="loading"></div>
    </center>
  <div class="row row-cols-1 row-cols-md-3 g-4" id="data"></div>
</div>

Next, we will define our Async function.

<script>  
const api_url =
    "https://catfact.ninja/breeds";

// Defining async function
  async function getapi(url) {

  // Storing response
  const response = await fetch(url);

  // Storing data in form of JSON
  var data = await response.json();
  console.log(data);
  if (response) {
      hideloader();
  }
  show(data);
}
</script>

Next, we need to call the getapi function.

// Calling that async function
getapi(api_url);

Now, you should be able to see some data in your developer console.

Next, we iterate over the data and display them in the HTML tag.

// Loop to access all rows
  for (let item of data.data) {
      // let description = item.course_description.substring(0, 100).concat('...')
      tab += `
      <div class="col-12 col-md-6 mb-6 col-lg-4 d-flex">
      <div class="card shadow-light-lg mb-6 mb-md-0 lift lift-lg">
            <div class="card-body position-relative">
              <div class="position-relative text-right mt-n8 mr-n4 mb-3">
                <span class="badge badge-pill badge-success">
                  <span class="h6 text-uppercase"><i class="fa fa-check"></i></span>
                </span>
              </div>

              <h3 class="text-capitalize" style="font-family:poppins" >
                ${item.breed}
              </h3>

              <p class="text-muted">
                ${item.country}
              </p>

              <p>${item.origin}</p>

            </div>
            </div>
          </div>
          `;
  }
  // Setting innerHTML as tab variable
  document.getElementById("data").innerHTML = tab;
}

Now, we want to tie our function to the load event listener so that when the page loads, the function starts to run.

Here’s the full code:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <title>Modern Cat Breeds</title>
    <style>
      :root {
        --primary: #6C63FF;
        --primary-light: #8A84FF;
        --secondary: #FF6584;
        --dark: #2A2D3E;
        --light: #F7F9FC;
        --gray: #8C8E9A;
      }
      
      body {
        font-family: 'Poppins', sans-serif;
        background-color: var(--light);
        color: var(--dark);
        line-height: 1.6;
      }
      
      .navbar {
        background: linear-gradient(135deg, var(--primary), var(--primary-light));
        box-shadow: 0 4px 12px rgba(108, 99, 255, 0.15);
      }
      
      .hero-section {
        background: linear-gradient(135deg, var(--primary), var(--primary-light));
        color: white;
        padding: 80px 0;
        margin-bottom: 40px;
        border-radius: 0 0 30px 30px;
      }
      
      .card {
        border: none;
        border-radius: 16px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
        transition: all 0.3s ease;
        overflow: hidden;
        height: 100%;
      }
      
      .card:hover {
        transform: translateY(-8px);
        box-shadow: 0 12px 20px rgba(0, 0, 0, 0.1);
      }
      
      .card-header {
        background: linear-gradient(135deg, var(--primary), var(--primary-light));
        color: white;
        border: none;
        padding: 16px 20px;
        font-weight: 600;
      }
      
      .card-body {
        padding: 24px;
      }
      
      .country-flag {
        display: inline-block;
        width: 24px;
        height: 24px;
        border-radius: 50%;
        background: var(--secondary);
        color: white;
        text-align: center;
        line-height: 24px;
        font-size: 12px;
        margin-right: 8px;
      }
      
      .spinner-border {
        width: 3rem;
        height: 3rem;
        color: var(--primary);
      }
      
      .footer {
        background-color: var(--dark);
        color: white;
        padding: 40px 0;
        margin-top: 60px;
      }
      
      .stats-container {
        background: white;
        border-radius: 16px;
        padding: 24px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
        margin-bottom: 30px;
      }
      
      .stat-number {
        font-size: 2.5rem;
        font-weight: 700;
        color: var(--primary);
      }
      
      .stat-label {
        font-size: 0.9rem;
        color: var(--gray);
        text-transform: uppercase;
        letter-spacing: 1px;
      }
      
      .search-container {
        max-width: 500px;
        margin: 0 auto 30px;
      }
      
      .search-box {
        border-radius: 50px;
        padding: 12px 24px;
        border: 1px solid #e0e0e0;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
      }
      
      .search-box:focus {
        border-color: var(--primary);
        box-shadow: 0 4px 12px rgba(108, 99, 255, 0.15);
      }
      
      .no-results {
        text-align: center;
        padding: 40px;
        color: var(--gray);
      }
      
      .no-results i {
        font-size: 3rem;
        margin-bottom: 16px;
        color: #e0e0e0;
      }
    </style>
  </head>
  <body>
    <!-- Navigation -->
    <nav class="navbar navbar-expand-lg navbar-dark">
      <div class="container">
        <a class="navbar-brand fw-bold" href="#">
          <i class="fas fa-paw me-2"></i>Codeflare CatBreeds
        </a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
          <ul class="navbar-nav ms-auto">
            <li class="nav-item">
              <a class="nav-link active" href="#">Home</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Breeds</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">About</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Contact</a>
            </li>
          </ul>
        </div>
      </div>
    </nav>

    <!-- Hero Section -->
    <section class="hero-section">
      <div class="container text-center">
        <h1 class="display-4 fw-bold mb-3 text-light">Discover Cat Breeds</h1>
        <p class="lead mb-4 text-light">Explore the fascinating world of feline breeds from around the globe</p>
        <div class="search-container">
          <div class="input-group search-box">
            <span class="input-group-text bg-transparent border-0">
              <i class="fas fa-search text-muted"></i>
            </span>
            <input type="text" class="form-control border-0 bg-transparent" id="searchInput" placeholder="Search cat breeds...">
          </div>
        </div>
      </div>
    </section>

    <!-- Main Content -->
    <div class="container">
      <!-- Stats Section -->
      <div class="row mb-5">
        <div class="col-md-3 col-6">
          <div class="stats-container text-center">
            <div class="stat-number" id="totalBreeds">0</div>
            <div class="stat-label">Total Breeds</div>
          </div>
        </div>
        <div class="col-md-3 col-6">
          <div class="stats-container text-center">
            <div class="stat-number" id="totalCountries">0</div>
            <div class="stat-label">Countries</div>
          </div>
        </div>
        <div class="col-md-3 col-6">
          <div class="stats-container text-center">
            <div class="stat-number" id="uniqueOrigins">0</div>
            <div class="stat-label">Unique Origins</div>
          </div>
        </div>
        <div class="col-md-3 col-6">
          <div class="stats-container text-center">
            <div class="stat-number" id="avgCoat">0</div>
            <div class="stat-label">Avg. Coat Length</div>
          </div>
        </div>
      </div>

      <!-- Loading Spinner -->
      <div class="text-center py-5" id="loading">
        <div class="spinner-border" role="status">
          <span class="visually-hidden">Loading...</span>
        </div>
        <p class="mt-3 text-muted">Loading cat breeds...</p>
      </div>

      <!-- Breeds Grid -->
      <div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4" id="data"></div>
      
      <!-- No Results Message -->
      <div class="no-results d-none" id="noResults">
        <i class="fas fa-search"></i>
        <h4>No breeds found</h4>
        <p>Try adjusting your search terms</p>
      </div>
    </div>

    <!-- Footer -->
    <footer class="footer">
      <div class="container">
        <div class="row">
          <div class="col-md-6">
            <h5><i class="fas fa-paw me-2"></i>Codeflare CatBreeds</h5>
            <p class="mt-3">Discover and learn about various cat breeds from around the world.</p>
          </div>
          <div class="col-md-3">
            <h5>Quick Links</h5>
            <ul class="list-unstyled">
              <li><a href="#" class="text-light text-decoration-none">Home</a></li>
              <li><a href="#" class="text-light text-decoration-none">Breeds</a></li>
              <li><a href="#" class="text-light text-decoration-none">About</a></li>
              <li><a href="#" class="text-light text-decoration-none">Contact</a></li>
            </ul>
          </div>
          <div class="col-md-3">
            <h5>Connect</h5>
            <div class="d-flex mt-3">
              <a href="#" class="text-light me-3"><i class="fab fa-facebook-f"></i></a>
              <a href="#" class="text-light me-3"><i class="fab fa-twitter"></i></a>
              <a href="#" class="text-light me-3"><i class="fab fa-instagram"></i></a>
              <a href="#" class="text-light"><i class="fab fa-github"></i></a>
            </div>
          </div>
        </div>
        <hr class="my-4">
        <div class="text-center">
          <p>&copy; 2025 Codeflare CatBreeds. All rights reserved.</p>
        </div>
      </div>
    </footer>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>
    <script>
      window.addEventListener('load', (event) => {
        const api_url = "https://catfact.ninja/breeds";
        let allBreeds = [];

        // Defining async function
        async function getapi(url) {
          // Storing response
          const response = await fetch(url);

          // Storing data in form of JSON
          var data = await response.json();
          console.log(data);
          if (response) {
            hideloader();
          }
          allBreeds = data.data;
          updateStats(allBreeds);
          show(allBreeds);
        }

        // Calling that async function
        getapi(api_url);

        // Function to hide the loader
        function hideloader() {
          document.getElementById('loading').style.display = 'none';
        }

        // Update stats
        function updateStats(breeds) {
          document.getElementById('totalBreeds').textContent = breeds.length;
          
          const countries = [...new Set(breeds.map(item => item.country))];
          document.getElementById('totalCountries').textContent = countries.length;
          
          const origins = [...new Set(breeds.map(item => item.origin))];
          document.getElementById('uniqueOrigins').textContent = origins.length;
          
          // Calculate average coat length (mock data since API doesn't provide this)
          const avgCoat = (breeds.length / 3).toFixed(1);
          document.getElementById('avgCoat').textContent = avgCoat;
        }

        // Function to define innerHTML for HTML table
        function show(data) {
          let tab = ``;

          // Loop to access all rows
          for (let item of data) {
            // Get first two letters of country for flag icon
            const countryCode = item.country.substring(0, 2).toUpperCase();
            
            tab += `
            <div class="col">
              <div class="card h-100">
                <div class="card-header d-flex justify-content-between align-items-center">
                  <span>${item.breed}</span>
                  <span class="country-flag">${countryCode}</span>
                </div>
                <div class="card-body">
                  <div class="mb-3">
                    <small class="text-muted">Country</small>
                    <p class="mb-0">${item.country}</p>
                  </div>
                  <div class="mb-3">
                    <small class="text-muted">Origin</small>
                    <p class="mb-0">${item.origin}</p>
                  </div>
                  <div>
                    <small class="text-muted">Coat</small>
                    <p class="mb-0">${item.coat || 'Medium'}</p>
                  </div>
                </div>
                <div class="card-footer bg-transparent border-0 pt-0">
                  <button class="btn btn-sm btn-outline-primary">Learn More</button>
                </div>
              </div>
            </div>`;
          }
          
          // Setting innerHTML as tab variable
          document.getElementById("data").innerHTML = tab;
          
          // Show no results message if no data
          if (data.length === 0) {
            document.getElementById('noResults').classList.remove('d-none');
          } else {
            document.getElementById('noResults').classList.add('d-none');
          }
        }

        // Search functionality
        document.getElementById('searchInput').addEventListener('input', function(e) {
          const searchTerm = e.target.value.toLowerCase();
          const filteredBreeds = allBreeds.filter(item => 
            item.breed.toLowerCase().includes(searchTerm) || 
            item.country.toLowerCase().includes(searchTerm) ||
            item.origin.toLowerCase().includes(searchTerm)
          );
          show(filteredBreeds);
        });
      });
    </script>
  </body>
</html>

Here’s what the result looks like:

Conclusion

The Fetch API has become an essential part of modern JavaScript development, offering a more intuitive and flexible way to fetch resources from servers. Its simplicity, promise-based nature, and support for various data formats make it a powerful tool for building web applications that rely on dynamic data retrieval.

By leveraging the Fetch API, developers can handle asynchronous network requests with ease, handle errors gracefully, and customize requests to suit their application’s needs. Whether it’s fetching data from APIs, uploading files, or sending form data, the Fetch API provides a versatile solution.

As the web continues to evolve, the Fetch API remains a valuable addition to a JavaScript developer’s toolkit. By mastering this powerful API, developers can unlock new possibilities for creating fast, interactive, and data-driven web applications.

Build a New App with Javascript ES6

Share
Published by
codeflare

Recent Posts

The Golden Ratio (φ)

1. What Is the Golden Ratio? The Golden Ratio, represented by the Greek letter φ (phi), is…

2 days ago

CSS Combinators

In CSS, combinators define relationships between selectors. Instead of selecting elements individually, combinators allow you to target elements based…

4 days ago

Boolean Algebra

Below is a comprehensive, beginner-friendly, yet deeply detailed guide to Boolean Algebra, complete with definitions, laws,…

6 days ago

Why It’s Difficult to Debug Other People’s Code (And what Can be Done About it)

Debugging your own code is hard enough — debugging someone else’s code is a whole…

7 days ago

Complete Git Commands

Git is a free, open-source distributed version control system created by Linus Torvalds.It helps developers: Learn how to…

1 week ago

Bubble Sort Algorithm

Bubble Sort is one of the simplest sorting algorithms in computer science. Although it’s not…

1 week ago