← Back to all snippets
JAVASCRIPT

Creating a Reusable Data Fetching Composable

Learn how to build a custom Vue 3 Composable to encapsulate asynchronous data fetching logic, providing reactivity, loading states, and error handling for cleaner components.

// composables/useFetch.js
import { ref, onMounted, isRef, unref, watch } from 'vue';

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

  async function doFetch() {
    // reset state before fetching
    data.value = null;
    error.value = null;
    loading.value = true;

    try {
      const res = await fetch(unref(url));
      if (!res.ok) {
        throw new Error(`HTTP error! status: ${res.status}`);
      }
      data.value = await res.json();
    } catch (err) {
      error.value = err;
    } finally {
      loading.value = false;
    }
  }

  if (isRef(url)) {
    watch(url, doFetch, { immediate: true });
  } else {
    onMounted(doFetch);
  }

  return { data, error, loading, doFetch };
}

// Usage in a Vue Component:
// <template>
//   <div v-if="loading">Loading...</div>
//   <div v-else-if="error">Error: {{ error.message }}</div>
//   <div v-else>
//     <h1>{{ data.title }}</h1>
//     <p>{{ data.body }}</p>
//   </div>
// </template>

// <script setup>
// import { useFetch } from './composables/useFetch';
// import { ref } from 'vue';

// const postId = ref(1); // Example with reactive URL
// const { data, error, loading } = useFetch(() => `https://jsonplaceholder.typicode.com/posts/${postId.value}`);

// // Or static URL:
// // const { data, error, loading } = useFetch('https://jsonplaceholder.typicode.com/todos/1');

// // Example to refetch
// // function fetchNextPost() {
// //   postId.value++;
// // }
// </script>
How it works: This snippet demonstrates a custom `useFetch` Composable for Vue 3. It encapsulates the logic for making an asynchronous API call, managing loading and error states, and exposing them reactively. It supports both static and reactive URLs, automatically refetching when a reactive URL changes, making data fetching reusable across components.

Need help integrating this into your project?

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

Hire DigitalCodeLabs