Tutorial Melakukan Fetching Data Menggunakan JavaScript

Fetching data merupakan teknik bagaimana sebuah aplikasi melakukan permintaan resource pada server tertentu dan mengembalikan data tersebut sesuai dengan permintaan. Pada artikel kali ini kita akan membahas bagaimana melakukan Fetching data menggunakan Javascript menggunakan kata kunci fetch.

Syntax

fetch('url')
    .then(result => {
        // handle result here
    }).catch(error => {
        // handle error here
    })

Mari kita analisis:

  1. Fungsi fetch pada JavaScript menerima satu parameter bertipe data string, yaitu endpoint atau URL dimana kita akan melakukan proses permintaan data pada resource tertentu.
  2. Kemudian karena fungsi fetch merupakan sebuah Promise, maka kita perlu melakukan proses chaining dengan fungsi then agar mendapatkan data yang diinginkan.
  3. Ketika melakukan sebuah permintaan data menggunakan fetch, terkadang data yang diinginkan tidak dikembalikan sesuai permintaan. Hal tersebut terjadi karena server ataupun endpoint tersebut mengalami error yang tidak kita ketahui. Untuk mengatasi hal tersebut kita wajib melakukan error handling, yaitu dengan cara memanggil fungsi catch. Fungsi catch ini mendapatkan semua error baik saat melakukan proses pemanggilan data ataupun kesalahan saat proses development.

Implementasi

Kita akan mencoba untuk hit endpoint yang disediakan oleh website JSONPlaceholder untuk melakukan proses fetching sederhana menggunakan kata kunci fetch. Jadi mari kita mulai.

  1. Inisialisasi Project Silakan kamu buat folder dengan nama learn-fetching-data, kemudian buat file HTML dengan nama index.html dan script.js hal ini bertujuan agar kita memisahkan antara bagian logic dan proses render menjadi file terpisah. Dalam project kali ini kita akan menggunakan Tailwind CSS sebagai proses styling, maka didapatkan:
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Sample API Data</title>
      <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&display=swap" rel="stylesheet" />

      <style>
         body {
            font-family: "Poppins", sans-serif;
         }
      </style>

      <script src="https://cdn.tailwindcss.com"></script>
   </head>
   <body>
      <div class="container mx-auto px-5 mt-10">
         <h1 class="text-2xl font-bold mb-5">Belajar Fetching Data</h1>
         <div id="container" class="flex flex-col gap-5">
            <!-- Semua data akan dirender disini -->
         </div>
      </div>
      <script src="script.js"></script>
   </body>
</html>

Maka didapatkan hasil:

2. Lakukan Fetching Data Silakan kamu buka file script.js, kemudian kita akan melakukan proses fetching data dengan URL yang sudah kita siapkan sebelumnya, maka didapatkan:

const fetchAllTodos = () => {
    return fetch("https://jsonplaceholder.typicode.com/posts")
        .then((response) => {
            if (!response.ok) {
                throw new Error('Network response was not ok.');
            }
            return response.json();
        })
        .then((data) => {
            console.log(data);
            return data;
        })
        .catch((error) => {
            return error;
        });
};

fetchAllTodos();

Maka apabila kita buka browser dan pada bagian console akan didapatkan data sebagai berikut:

Seperti keterangan console di atas, kita sudah berhasil melakukan proses pengambilan data dengan menggunakan kata kunci fetch pada JavaScript. Selanjutnya kita akan menampilkan data tersebut ke dalam bentuk komponen UI yang sederhana.

3. Implementasikan Kedalam UI Untuk membuat hasil fetching data menjadi sebuah komponen HTML dan mudah dibaca, kita perlu membuat design nya terlebih dahulu. Berikut komponen Card yang akan kita gunakan untuk menampilkan data tersebut:

<div class="border rounded-md p-4 flex justify-between items-start gap-x-3">
   <div>
      <h1 class="font-bold mb-3">Lorem ipsum dolor sit amet.</h1>
      <span class="text-sm text-gray-500">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eum, suscipit?</span>
   </div>
   <div>
      <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
         <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
      </svg>
   </div>
</div>

Maka apabila kita padukan dengan baris HTML pada langkah pertama, didapatkan kode sebagai berikut:

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Sample API Data</title>
      <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&display=swap" rel="stylesheet" />

      <style>
         body {
            font-family: "Poppins", sans-serif;
         }
      </style>

      <script src="https://cdn.tailwindcss.com"></script>
   </head>
   <body>
      <div class="container mx-auto px-5 mt-10">
         <h1 class="text-2xl font-bold mb-5">Belajar Fetching Data</h1>
         <div id="container" class="flex flex-col gap-5">
            <!-- Semua data akan dirender disini -->
            <div class="border rounded-md p-4 flex justify-between items-start gap-x-3">
               <div>
                  <h1 class="font-bold mb-3">Lorem ipsum dolor sit amet.</h1>
                  <span class="text-sm text-gray-500">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eum, suscipit?</span>
               </div>
               <div>
                  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
                     <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                  </svg>
               </div>
            </div>
         </div>
      </div>
      <script src="script.js"></script>
   </body>
</html>

Pada langkah ini kita sudah berhasil membuat design komponen Card, hanya saja data tersebut belum sesuai dengan hasil fetching kita. Maka kita perlu menjadikannya dinamis dengan cara membuat fungsi yang me-render komponen Card yang barusan kita dibuat. Silahkan kamu buka file script.js dan tambahkan kode berikut:

// Ambil tag id container
const containerDisplay = document.getElementById('container')

// Komponen Card untuk render semua data
const cardComponent = (title, body) => {
    // Buat Card
    const data = `
        <div class="border rounded-md p-4 flex justify-between items-start gap-x-3">
            <div>
               <h1 class="font-bold mb-3">${title}</h1>
               <span class="text-sm text-gray-500">${body}</span>
            </div>
            <div>
               <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
                  <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
               </svg>
            </div>
         </div>
    `

    // Tambahkan kedalam elemen container yang sudah kita definisikan sebelumnya
    containerDisplay.insertAdjacentHTML('afterbegin', data)
}

Kemudian kita buat sebuah fungsi bernama render untuk menggabungkan antara fungsi fetchAllTodos yang sudah kita definisikan sebelumnya dengan fungsi cardComponent yang barusan kita buat.

function render() {
    fetchAllTodos()
        .then((response) => {
            response.forEach(result => {
                cardComponent(result.title, result.body);
            });
        })
        .catch((error) => {
            console.error('Error rendering data:', error);
        });
}

render();

Maka apabila kita buka browser akan didapatkan hasil seperti ini:

Taraa! Selamat kalian telah berhasil melakukan fetching data dan menampilkannya ke dalam komponen HTML yang mudah dibaca. Pada langkah selanjutnya kita akan mencoba melakukan Handle Error untuk mengantisipasi terjadinya kesalahan baik itu dari aplikasi kita maupun dari sisi server.

4. Handle Error Pertama kita buat komponen HTML nya terlebih dahulu dan kita sebut sebagai komponen Alert:

<div class="m-10 border border-red-700 text-red-700 bg-red-100 p-10 rounded-lg flex flex-col items-center gap-3">
   <div class="flex gap-x-3">
      <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
         <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
      </svg>
      <h1 class="font-bold text-center md:text-xl lg:text-2xl">Terjadi Kesalahan</h1>
   </div>
   <span class="text-sm text-center text-red-600"><span class="font-bold">Error Message :</span> Some Error</span>
</div>

Didapatkan bentuk seperti ini:

Lalu buat fungsi untuk menampung komponen Alert tersebut seperti komponen Card sebelumnya, didapatkan:

// Komponen Alert jika terdapat error
const alertComponent = (message) => {
    const data = `
    <div class="m-10 border border-red-700 text-red-700 bg-red-100 p-10 rounded-lg flex flex-col items-center gap-3">
        <div class="flex gap-x-3">
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
                <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
            </svg>
            <h1 class="font-bold text-center md:text-xl lg:text-2xl">Terjadi Kesalahan</h1>
        </div>
        <span class="text-sm text-center text-red-600"><span class="font-bold">Error Message :</span> ${message}</span>
    </div>
 `
    containerDisplay.insertAdjacentHTML('afterbegin', data)
}

Kemudian kita implementasikan ke dalam fungsi render sebelumnya, didapatkan:

function render() {
    fetchAllTodos()
        .then((response) => {
            response.forEach(result => {
                cardComponent(result.title, result.body);
            });
        })
        .catch((error) => {
            alertComponent(error.message)
        });
}

render();

Maka dengan ini apabila terdapat error, maka fungsi AlertComponent akan berjalan dan menampilkannya sebagai komponen HTML sesuai dengan yang kita harapkan. Berikut ini kode keseluruhan file index.html dan script.js yang telah kita buat:

File index.html

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Sample API Data</title>
      <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&display=swap" rel="stylesheet" />

      <style>
         body {
            font-family: "Poppins", sans-serif;
         }
      </style>

      <script src="https://cdn.tailwindcss.com"></script>
   </head>
   <body>
      <div class="container mx-auto px-5 mt-10">
         <h1 class="text-2xl font-bold mb-5">Belajar Fetching Data</h1>
         <div id="container" class="flex flex-col gap-5"></div>
      </div>
      <script src="script.js"></script>
   </body>
</html>

File script.js

// Ambil tag id container
const containerDisplay = document.getElementById('container')

// Komponen Card untuk render semua data
const cardComponent = (title, body) => {
    // Buat Card
    const data = `
        <div class="border rounded-md p-4 flex justify-between items-start gap-x-3">
            <div>
               <h1 class="font-bold mb-3">${title}</h1>
               <span class="text-sm text-gray-500">${body}</span>
            </div>
            <div>
               <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
                  <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
               </svg>
            </div>
         </div>
    `

    // Tambahkan kedalam elemen container yang sudah kita definisikan sebelumnya
    containerDisplay.insertAdjacentHTML('afterbegin', data)
}

// Komponen Alert jika terdapat error
const alertComponent = (message) => {
    const data = `
    <div class="m-10 border border-red-700 text-red-700 bg-red-100 p-10 rounded-lg flex flex-col items-center gap-3">
        <div class="flex gap-x-3">
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
                <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
            </svg>
            <h1 class="font-bold text-center md:text-xl lg:text-2xl">Terjadi Kesalahan</h1>
        </div>
        <span class="text-sm text-center text-red-600"><span class="font-bold">Error Message :</span> ${message}</span>
    </div>
 `
    containerDisplay.insertAdjacentHTML('afterbegin', data)
}

// Fungsi untuk mendapatkan semua data fetch
const fetchAllTodos = () => {
    return fetch("https://jsonplaceholder.typicode.com/posts")
        .then((response) => {
            if (!response.ok) {
                throw new Error('Network response was not ok.');
            }
            return response.json();
        })
        .catch((error) => {
            return error;
        });
};

function render() {
    fetchAllTodos()
        .then((response) => {
            response.forEach(result => {
                cardComponent(result.title, result.body);
            });
        })
        .catch((error) => {
            alertComponent(error.message)
        });
}

render();

Kesimpulan

Tentu saja artikel ini hanya mencakup dasar fetching data dan bagaimana implementasinya dalam project sederhana. Kita juga dapat mengkombinasikan fetching data menggunakan framework JavaScript seperti React atau Vue untuk membangun sebuah website yang lebih interaktif dan efisien.

Kalian bisa mulai latihan menggunakan framework JavaScript dengan cara mempelajari beberapa kelas online di BuildWithAngga. Jadi tunggu apa lagi? Mari bergabung dan sampai jumpa di kelas!