Automatic pending state for data being fetched?
TLDR: Does anyone know if there exists a way to wrap variables in a sort of suspense wrapper that will trigger a loading indicator whenever it registers that its content is currently being fetched or re-fetched? 🧐
I know I could manually create a "pending" variable and set it to false/true before and after a fetch, however as the application scales the amount of different pending variables I would need grows and I don't want to store them all in objects (ex. loading = {title: true, paragraph: false, etc....}) 🔥
useFetch has a "status" return value which can be used to detect the status of a fetch, but this only works when the page is originally loaded and not on fetches triggered by user interaction (ex. clicking a fetch button)
Does a loading wrapper exist or does anyone have an idea for how to implement one? Is there a way to check whether data within a component is currently being awaited?
Example:
<wrapper>{{ data }}</wrapper>
The wrapper should detect when data inside of it is being awaited (just checking if data is null doesn't work because we might want to refetch data, and I don't want to set it to null each time before refetch)
Any thoughts or suggestions would be much appreciated🙏
19 Replies
Glad to help you with this. Can you please share your current code and what sort it you’re trying to fetch and what sort of data do you want to fetch in the
The data fetching composables (useFetch, useAsyncData), already have a
status
property you can leverageRight, but it seems to me that useFetch() is only used on page load and not on user interaction. Screenshot is from https://nuxt.com/docs/getting-started/data-fetching
Nuxt
Data fetching · Get Started with Nuxt
Nuxt provides composables to handle data fetching within your application.
No that's not the case. You can use useFetch in all kinds of scenarios, also on user interaction
But this doesn't solve the issue of having multiple pending variables if I have 100 different fields that I need to fetch with each their "loading" fallback text.
What issue do you run into with that? (You can rename the variables btw:
const { state: field1State } = useFetch()
)Right, but what I would really love is to automatically detect that data is being awaited and whenever it is, display some arbitrary loading indicator. I know this can be done with <Suspense/> in React for example, but again this only applies to first time the data is being fetched it seems
Take a look at my example in my post:
I want a wrapper around any data, that will show the data if it is fetched or default to a loading indicator.
This would mean that in my main app I could handle all the data fetching and as long as i wrap my data in this wrapper:
<wrapper>{{data}}</wrapper>
or pass it as a prop
<wrapper :data="data"/>
Would show "loading" or "data" depending on the fetchstate of the given data
<wrapper :status="status">{{ data }}</wrapper>
then handle the status logic in the wrapper component?what about a custom $fetch wrapper? (btw. your are right: useFetch only should be used for getting data, not for update or create requests, for that
$fetch
should be used, thats because of internal caching logic behind useAsyncData / useFetch i guess)
Anyways.
for $fetch the same could be used. e.g. implement a global $myFetch via plugin, or just using a composable like:
Which can be called in components
plugin would be more elegant way to inject $myFetch globally.
Anyways, i think you got the point. Have a state which is aware of pending requests in you application, by intercept the requests by its core methods 😄Checked the source code:
https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/composables/asyncData.ts#L251C5-L257C6
This is what happens behind
useFetch
and useAsyncData
you could use that to get all the status
references and return a bool to know if any useFetch or useAsyncData is pending / refreshing.
For the custom $fetch
here is an example for the plugin way:
https://nuxt.com/docs/guide/recipes/custom-usefetchNuxt
Custom useFetch in Nuxt · Recipes
How to create a custom fetcher for calling your external API in Nuxt 3.
GitHub
nuxt/packages/nuxt/src/app/composables/asyncData.ts at main · nuxt/...
The Intuitive Vue Framework. Contribute to nuxt/nuxt development by creating an account on GitHub.
Thanks a lot! This looks promising
Do you think that a variable that is currently being assigned to an awaited fetch has some tell? For example:
I would like the message variable to reveal a pending state when awaiting assignment.
I tried checking whether my variable == Promise, but this didn't work
Do i get it correctly, you wan't some logic like the default from
useAsyncData
where you don't only have the Promise, instead also can access the fields like data
, error
, status
and so on without the Promise is done?
you could do it like nuxt:
its similar like in the useAsyncData
https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/composables/asyncData.ts#L395-L398
but there the data
and pending
is a reference / reactive prop itself.
So a better example would be:
Which could be accessed by a similar logic
PS: Code is not tested, maybe it need adjustements 🙂Thanks @Mähh
I would really like to not have to initialize my variables as objects with pending and data keys as this clutters the code.
My dream scenario is simply that I can somehow check if a variable is currently in a "fetching state"
For example imagine:
I wonder whether a value that is currently being assigned with await has some kind of metadata associated with it that I could query to trigger my loading animation.
Isn't that literally what
status
already does?Yes but can you show me an example of using "status" when fetching something on click without having to store it in a variable
Because if I need to store it in a variable I need different variables for each field. This is what I'm trying to avoid
Sure, sec
Unless you somehow use the interceptors to track a "global" count of fetch requests, you'll have to do some manual tracking :https://stackblitz.com/edit/github-tfsw15?file=app.vue
StackBlitz
Nuxt - Starter - StackBlitz
Create a new Nuxt project, module, layer or start from a theme with our collection of starters.
This comment has a good solution to doing it automatically: https://discord.com/channels/473401852243869706/1263445640537702421/1263513911714381976
But the caveat is that this will track every fetch request, not just the ones you might want to track "locally"