Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useAsyncData in middleware gives warning to use $fetch when changing route to the same pageComponent #25661

Open
MarijnFK opened this issue Feb 6, 2024 · 14 comments

Comments

@MarijnFK
Copy link

MarijnFK commented Feb 6, 2024

Environment


  • Operating System: Darwin
  • Node Version: v18.19.0
  • Nuxt Version: 3.10.0
  • CLI Version: 3.10.0
  • Nitro Version: 2.8.1
  • Package Manager: [email protected]
  • Builder: -
  • User Config: -
  • Runtime Modules: -
  • Build Modules: -

Reproduction

https://stackblitz.com/edit/nuxt-starter-haznex?file=middleware/single.ts

Describe the bug

Not sure if this is a bug or something i use incorrectly.

we use a middleware to fetch data based on a dynamic route (slug)
this gives a warning to use $fetch, because the component is already mounted:

[nuxt] [useAsyncData] Component is already mounted, please use $fetch instead. See https://nuxt.com/docs/getting-started/data-fetching

Additional context

We use a middleware so we have access to the page data before entering the page.
This way we can get the localized slugs in the middleware and set them on the $i18n module like so:
to.meta.nuxtI18n = localizedSlugs;

Logs

No response

Copy link

stackblitz bot commented Feb 6, 2024

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

@danielroe
Copy link
Member

Is there a reason you don't want to use $fetch?

@MarijnFK
Copy link
Author

MarijnFK commented Feb 6, 2024

we are using @nuxtjs/strapi to fetch the data from strapi, and according to their specifications we should use useAsyncData to enable SSR. We suppose we cannot use $fetch in combination with @nuxtjs/strapi

See this documentation: https://strapi.nuxtjs.org/advanced#async-data

@c-schwan
Copy link
Contributor

c-schwan commented Feb 6, 2024

Just use findOne without useAsyncData in the middleware

@MarijnFK
Copy link
Author

MarijnFK commented Feb 7, 2024

does that work with SSR and payload extraction?

@MarijnFK
Copy link
Author

MarijnFK commented Feb 7, 2024

And the new shared async data cannot be used this way: https://nuxt.com/blog/v3-10?ref=dailydev

@GreenBabyBorn
Copy link

I have the same issue with middleware in lucia-auth (https://github.com/lucia-auth/examples/blob/main/nuxt/username-and-password/middleware/auth.global.ts)

@kouts
Copy link

kouts commented Feb 11, 2024

Confirming that I have the same issue with lucia-auth middleware.

@BBoehm
Copy link

BBoehm commented Mar 9, 2024

Is there a reason you don't want to use $fetch?

@danielroe
According to the dollarfetch documentation, that would cause the data to be loaded twice - unless it works different in the middleware?

Also, the warning states, that the component would be already mounted - while the middleware should be independant of components? Is that just a confusing warning message then?

@danielroe
Copy link
Member

@BBoehm It really depends. But yes, every time you call $fetch the request will be made fresh. You could use useState to avoid that. Or directly access and manipulate nuxtApp.payload. I wouldn't call useAsyncData on each route navigation though... That will perform additional requests every time you change page, even though it won't do so on initial load.

@Frallen
Copy link

Frallen commented Apr 7, 2024

nuxtApp.payload

To prevent repeated requests, you can use nuxt.payload or useState.

In my case, I use pinia, which stores the data. To prevent a repeat request, I check if my storage is full and if the ID matches. If the storage is empty, then I make a request, if the id does not match, then I make a request (if it matches, then there will be no request). The same can be done using user State.

I created a discussion about this

import type { StateTree } from "pinia";

export default defineNuxtRouteMiddleware(async (to, from) => {
    const {payload}=useNuxtApp()
    const { Conversation } = storeToRefs(useChat());
    const { getDialog } = useChat();
    let state = payload.pinia as Record<string, StateTree>;
// inital load, check object or check id
    if (
        Object.keys(state.chat.Conversation).length < 1 ||
        to.params.id !== state.chat.Conversation.id.toString()
    ) {
        await getDialog(<string>to.params.slug, <string>to.params.id);
    }

//404
    if (Object.keys(Conversation.value).length < 1) {
        return abortNavigation();
    }
});

@kouts
Copy link

kouts commented Apr 7, 2024

Confirming that I have the same issue with lucia-auth middleware.

I managed to fix it using useRequestFetch() instead.
#23423

@danielroe danielroe removed the 3.x label Jun 30, 2024
@johankrijt
Copy link
Contributor

We are experiencing the same warning: Component is already mounted, please use $fetch instead. In our project we are using global route middleware to check some main attributes and user data (both fetched from our internal api using useFetch). There is no worry for additional requests as this should be caught by the getCachedData option, unless you intentionally change the usage like we do (custom useFetch adding ttl and force reload to the getCachedData function).

I couldn't find any reason reading through this issue why useFetch shouldn't or can't be used in route middleware (it even states it can be used in the documentation: 'meant to be called directly in a setup function, plugin, or route middleware'), so in my opinion the warning should not include the component instance check it does right now.

@ColonelBundy
Copy link

To me, the warning in useAsyncData targets a specific use case. Our use case is not about fetching data that can be replaced using $fetch. According to the recommendations, useAsyncData should be used when useState cannot be used, which is precisely the case we're facing. While you ccertainly can work around the async issue of useState the boilerplate for each instance of this is quite large, which useAsyncData handles beautifully for you.
The warning is valid for situations where $fetch can be used, this does not apply to our case and works as intended.

Since the $fetch scenario is probably the most common one, either a slight revision to better detect this issue is in order, or an option to turn off this warning should be provided, as it can be quite cumbersome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants