How to fetch and transform data with useAsyncData and Nuxt Content? – Nuxt.js

by
Alexei Petrov
nuxt-content nuxt.js nuxt3 nuxtjs3

Quick Fix: Utilize server-side data manipulation by operating on variables within the <script setup> block. Retrieve and sort the data using useAsyncData and queryContent, then format it using formatConcerts before assigning it to reactive variables.

The Problem:

A developer is using Nuxt and Nuxt Content to fetch and display data from a CSV file. They have successfully used the useAsyncData composable to fetch the data, but they need to transform the data using two different functions before displaying it. They tried using the transform option on the useAsyncData composable, but it didn’t work. They came up with a solution that involves using computed properties to sort and format the data, but it only works in development mode when wrapped in a <ClientOnly> component. When deploying the application, the data is only displayed the first time a route is visited and is empty on subsequent visits. The developer is seeking a solution to achieve their goal of fetching, transforming, and displaying the data correctly in both development and production.

The Solutions:

Solution 1: Manipulate Variables on the Server-Side

You can try this approach:

1. Define Reactive Variables:

  • Define reactive variables, such as sorted and concerts, using the ref() function within the <script setup>.

2. Use useAsyncData to Fetch Data:

  • Use useAsyncData to fetch data from the content repository.

3. Transform Data on the Server-Side:

  • Inside the .then() callback of useAsyncData, transform the data using the desired functions (sortConcerts and formatConcerts) on the server-side (during prerendering).
  • Assign the transformed data to the reactive variables (sorted and concerts).

4. Access Transformed Data:

  • In the template, you can access the transformed data using the reactive variables, ensuring that the data is available for display on the client-side.

Using this approach, the data manipulation and transformation occur during server-side rendering, ensuring that the transformed data is available for display on the client-side, even after the initial page load. This should resolve the issue with data disappearing after the first visit to the route.

This solution ensures that all the necessary data manipulation and transformation are performed on the server-side during prerendering, resulting in a more efficient and reliable data handling process.

Solution 2: Using refs for data and computeds

In this solution, we’ll use refs to store the data and computed properties to transform it. Here’s an improved explanation of how it works:

  1. Define refs for data and computeds:
    const sorted = ref()
    const concerts = ref()
    

    We use refs to store the sorted concerts and the final transformed concerts.

  2. Fetch data with useAsyncData:
    const { data } = await useAsyncData('concerts', () => queryContent('/concerts').findOne())
    

    We fetch the data from the API using useAsyncData and store the result in the data ref.

  3. Transform data after fetching:
    if (data.value) {
      sorted.value = data.value?.body
      concerts.value = formatConcerts(sorted.value, en)
    }
    

    Once the data is available, we check if it exists and then transform it using the sortConcerts and formatConcerts functions. The result is stored in the sorted and concerts refs.

  4. Use computed properties in the template:
    <template>
      <ul>
        <li v-for="concert in concerts" :key="concert.id">
          {{ concert.name }}
        </li>
      </ul>
    </template>
    

    In the Vue template, we use computed properties to access the transformed concerts data and display it in a list.

This approach ensures that the data is fetched and transformed only once, and the transformed data is available for use in the template.

Q&A

Why my sorted data is empty in production environment?

Try to manipulate the variables on the server-side (prerender).

How can i get the data from the composable in the setup method?

You can use .then() to handle the promise returned by useAsyncData composable and assign the result to the variables in the setup method.

Video Explanation:

The following video, titled "Nuxt 3 | Data fetching | useAsyncData | useFetch ...", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

Hi all, Thanks a lot guys for voting in the poll that I ran last week. It was super helpful. As per the majority, here is the video on Nuxt ...