← Back to all snippets
JAVASCRIPT

Reusable Data Fetching Composable with Loading & Error States

Create a robust and reusable data fetching composable in Vue 3 using the Composition API, handling loading, error, and data states efficiently.

import { ref, watchEffect } from 'vue';

export function useFetch(url) {
  const data = ref(null);
  const error = ref(null);
  const loading = ref(true);

  watchEffect(async () => {
    loading.value = true;
    error.value = null;
    data.value = null;
    try {
      const response = await fetch(url.value || url);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      data.value = await response.json();
    } catch (e) {
      error.value = e;
    } finally {
      loading.value = false;
    }
  });

  return { data, error, loading };
}

// How to use in a component:
// <script setup>
// import { ref } from 'vue';
// import { useFetch } from './composables/useFetch';
//
// const postId = ref(1);
// const url = ref(`https://jsonplaceholder.typicode.com/posts/${postId.value}`);
// const { data, error, loading } = useFetch(url);
//
// function fetchNextPost() {
//   postId.value++;
//   url.value = `https://jsonplaceholder.typicode.com/posts/${postId.value}`;
// }
// </script>
//
// <template>
//   <div>
//     <button @click="fetchNextPost">Fetch Next Post</button>
//     <div v-if="loading">Loading...</div>
//     <div v-else-if="error">Error: {{ error.message }}</div>
//     <div v-else-if="data">
//       <h2>{{ data.title }}</h2>
//       <p>{{ data.body }}</p>
//     </div>
//   </div>
// </template>
How it works: This composable (`useFetch`) encapsulates the logic for fetching data, managing loading and error states. It leverages Vue 3's `ref` for reactive state and `watchEffect` to automatically re-run the fetch operation whenever the URL dependency changes. This pattern promotes code reusability across different components, making data fetching concerns easy to manage and test. The example shows how to use it by dynamically updating the URL to fetch new data.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs