Introduction
In this article, we'll explore how to fetch and display data using useAsyncData in Nuxt 3. We'll pull data from a mock API, transform the response, and display it in a dynamic grid layout. We'll also handle potential errors and loading states gracefully.
Prerequisites
To follow along, you need:
- A basic understanding of Vue 3 and Nuxt 3
- A Nuxt 3 project set up
Code Implementation
Script Section
Here's the script section of our component:
<script setup>
import { useAsyncData, useFetch } from "nuxt/app";
const { pending, data: productInfo, refresh, error } = useAsyncData(
"productInfo",
async () => {
const [products, categories] = await Promise.all([
$fetch("https://fakestoreapi.com/products"),
$fetch("https://fakestoreapi.com/products/categories"),
]);
return {
products,
categories,
};
},
{
lazy: false,
transform: (productInfo) => {
if (!productInfo || !productInfo.products) {
throw new Error("Invalid API response");
}
return {
categories: productInfo.categories,
products: productInfo.products.map((product) => ({
id: product.id,
title: "product.title,"
image: product.image,
})),
};
},
onError: (err) => {
console.error("Error fetching data:", err);
},
}
);
</script>
ย Template Section
In the template section, we handle the pending, error, and success states with appropriate UI elements:
<template>
<div v-if="pending">
<p>Loading...</p>
</div>
<div v-else-if="error">
<p>Error fetching data: {{ error.message }}</p>
</div>
<div v-else>
<button @click="refresh">Refresh Data</button>
<div class="grid grid-cols-5 gap-4">
<div
v-for="product in productInfo.products"
:key="product.id"
class="flex flex-col shadow-md bg-white p-6 rounded-md"
>
<img class="w-[75px] h-auto self-center" alt="" :src="product.image" />
<h2 class="text-black mt-auto text-sm">{{ product.title }}</h2>
</div>
</div>
</div>
</template>
Styling
For simplicity, we use a scoped style block:
<style scoped>
/* Add your custom styles here */
</style>
Key Features Explained
1. Fetching Data with useAsyncData
useAsyncData simplifies data fetching in Nuxt 3 by handling reactivity, server-side rendering, and caching. We use it to fetch products and categories data in parallel using Promise.all.
2. Transforming Data
We use the transform option to process the API response before returning it. This ensures the data is formatted as needed for our template.
3. Error Handling
Errors are handled in two ways:
- Inside the
transformfunction, we check for valid API responses and throw errors for unexpected data. - The
onErrorhook logs errors for debugging.
4. UI States
We handle three main states:
-
Loading: Displayed while the data is being fetched (
pending). -
Error: Displayed when an error occurs during data fetching (
error). - Success: Displays the product grid when data is successfully fetched.
Running the Project
- Start your Nuxt development server:
npm run dev
- Open the application in your browser to see the dynamic product grid.
Conclusion
This example demonstrates how useAsyncData in Nuxt 3 makes data fetching and handling straightforward. By leveraging its features like transformations, lazy loading, and error handling, you can build robust, dynamic web applications with ease.
Top comments (0)