← Back to all snippets
JAVASCRIPT

Creating a Reusable Composable for Asynchronous Data Fetching

Learn to build a custom Vue 3 composable to encapsulate data fetching logic, providing reactive state for loading, error, and data, promoting code reuse.

// composables/useFetch.js
import { ref, watchEffect, toValue } from 'vue';

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

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

    try {
      const response = await fetch(toValue(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 };
}

// In a Vue component (e.g., MyComponent.vue)
<template>
  <div>
    <h1>Posts</h1>
    <p v-if="loading">Loading posts...</p>
    <p v-if="error">Error: {{ error.message }}</p>
    <ul v-if="data">
      <li v-for="post in data" :key="post.id">{{ post.title }}</li>
    </ul>
  </div>
</template>

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

const { data, error, loading } = useFetch('https://jsonplaceholder.typicode.com/posts');
</script>
How it works: This snippet demonstrates how to create a custom composable, `useFetch`, for abstracting asynchronous data fetching logic in Vue 3. It utilizes `ref` for reactive state (`data`, `error`, `loading`) and `watchEffect` to automatically re-fetch data whenever the URL changes. This promotes reusability and clean separation of concerns, making data fetching manageable across multiple components.

Need help integrating this into your project?

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

Hire DigitalCodeLabs