DEV Community

A0mineTV
A0mineTV

Posted on

πŸš€ Fetching and Displaying Data in Nuxt 3 with useAsyncData

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>
Enter fullscreen mode Exit fullscreen mode

Β 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>
Enter fullscreen mode Exit fullscreen mode

Styling

For simplicity, we use a scoped style block:

<style scoped>
/* Add your custom styles here */
</style>
Enter fullscreen mode Exit fullscreen mode

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 transform function, we check for valid API responses and throw errors for unexpected data.
  • The onError hook 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
Enter fullscreen mode Exit fullscreen mode
  • 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)