useFetch: Async Data Composable
data, loading, error refs, fetch on mount, refetch function, AbortController cleanup.
useFetch: Async Data Composable is a free Vue Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Vue Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
The useFetch Goal
Async data fetching repeats everywhere: loading flags, error handling, the request itself. useFetch bundles this into one reusable composable returning data, loading, and error.
The Three Reactive Refs
Start with three refs that describe any async request state.
import { ref } from "vue";
function useFetch(url) {
const data = ref(null);
const loading = ref(false);
const error = ref(null);
}The Fetch Routine
Write an async function that flips loading, performs the request, and stores the result. We will refine error handling next.
async function execute() {
loading.value = true;
const res = await fetch(url);
data.value = await res.json();
loading.value = false;
}try / catch / finally
Wrap the request so errors land in error and loading always resets, success or failure, in finally.
async function execute() {
loading.value = true;
error.value = null;
try {
const res = await fetch(url);
if (!res.ok) throw new Error("HTTP " + res.status);
data.value = await res.json();
} catch (e) {
error.value = e;
} finally {
loading.value = false;
}
}Fetching in onMounted
Kick off the request when the component mounts so data loads automatically.
import { onMounted } from "vue";
onMounted(execute);A refetch Function
Expose execute as refetch so consumers can reload on demand - after a mutation or a retry button.
return { data, loading, error, refetch: execute };AbortController for Cleanup
If the component unmounts mid-request, abort the fetch to avoid setting state on a dead component. Create an AbortController and pass its signal.
const controller = new AbortController();
const res = await fetch(url, { signal: controller.signal });Aborting on Unmount
Cancel the in-flight request in onUnmounted. Ignore the resulting abort error in the catch.
import { onUnmounted } from "vue";
onUnmounted(() => controller.abort());The Full useFetch
Assembled, the composable handles loading, errors, refetching, and cleanup in one tidy unit.
function useFetch(url) {
const data = ref(null);
const loading = ref(false);
const error = ref(null);
const controller = new AbortController();
async function execute() {
loading.value = true; error.value = null;
try {
const res = await fetch(url, { signal: controller.signal });
data.value = await res.json();
} catch (e) {
if (e.name !== "AbortError") error.value = e;
} finally {
loading.value = false;
}
}
onMounted(execute);
onUnmounted(() => controller.abort());
return { data, loading, error, refetch: execute };
}Using It in a Component
Consumers render based on the three refs - a spinner while loading, an error message on failure, the data otherwise.
const { data, loading, error } = useFetch("/api/posts");Template Pattern
Branch on the state in the template for a complete UX.
<p v-if="loading">Loading...</p>
<p v-else-if="error">{{ error.message }}</p>
<ul v-else>
<li v-for="p in data" :key="p.id">{{ p.title }}</li>
</ul>Quick Check
What is the role of AbortController in useFetch?
Recap
You built useFetch(url) exposing data, loading, and error refs, fetching in onMounted with a try/catch/finally pattern, a refetch function, and an AbortController cleaned up in onUnmounted.
Frequently asked questions
Is the “useFetch: Async Data Composable” lesson free?
Yes — the full text of “useFetch: Async Data Composable” is free to read here on the web, and the Vue Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Vue Academy course, upgrade to CoddyKit PRO.
What will I learn in “useFetch: Async Data Composable”?
data, loading, error refs, fetch on mount, refetch function, AbortController cleanup. You practise Vue Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Vue Academy?
No prior experience is required. Vue Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “useFetch: Async Data Composable” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Vue Academy lesson?
Yes. Every Vue Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- What Makes a Good Composable
- useCounter: A Simple Composable
- useFetch: Async Data Composable
- VueUse: The Composable Library