useAsyncData in composables that uses each other
Hi, everyone! π
I have a repo here: https://gitlab.com/HIV/budgettracker
The description:
I have a composable
useTransactionGroups
(B) and useTransactions
(A)
Both of them are supposed to run server-side on initial load.
(B) uses (A) to compute groups
property.
(B) is used on transactions
page and the (A) is used in the TFilter
component.
the transactions
data is requested with useAsyncData
that (as per docs) is supposed to use useState
for the data it fetches to cache it.
The problem:
Whenever the app starts, it issues 2 requests to transactions
API endpoint from (A), because:
TFilter -> (A): filters
Transactions (page) -> (B): groups -> (A): transactions
What did I try:
1. use pinia store to join (A) + (B) data inside in one shot;
2. use closures in (A) and (B) to not to create two separate instances of (A);
3. use useSatate
to manage data inside (A) and (B)
If I use only (B) inside transactions
page and pass filter
and groups
as props to the corresponding components, everything works great.
The question:
What are the options to 'tear apart' single composable with useAsyncData
inside. I think I don't understand something and maybe composables are not even designed to work that way.
Thank you!2 Replies
Hi @DesiredName. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
Based on the information provided in the knowledge sources, I can offer some insights and suggestions regarding your question about using
useAsyncData
in composables that depend on each other.
The main issue you're facing is that multiple requests are being made to the same API endpoint, which is not the desired behavior when using useAsyncData
. This composable is designed to cache data and avoid duplicate requests. Let's explore some potential solutions:
1. Use a unique key for useAsyncData
:
One of the most important aspects of using useAsyncData
effectively is to provide a unique key. As mentioned in the Nuxt documentation (https://nuxt.com/docs/getting-started/data-fetching#suspense), it's recommended to always create your own key to avoid unwanted behavior, especially when creating custom composables that wrap useAsyncData
.
Try modifying your composables to use a consistent, unique key for the transactions data:
Ensure that this key is used consistently across both composables.
2. Use useNuxtData
to access cached data:
Instead of making separate calls in each composable, you can use useNuxtData
to access the cached value of a previous useAsyncData
call. This is explained in the useNuxtData documentation (https://nuxt.com/docs/api/composables/use-nuxt-data).
In your case, you could fetch the transactions data in composable A, and then access it in composable B using useNuxtData
:
3. Use the dedupe
option:
The useAsyncData
composable has a dedupe
option that can help prevent multiple simultaneous requests. As mentioned in the useAsyncData documentation (https://nuxt.com/docs/api/composables/use-async-data), you can set dedupe: 'defer'
to avoid making new requests if there's already a pending request:
4. Consider using sharedPrerenderData
:
If you're prerendering your site, you might benefit from enabling the sharedPrerenderData
experimental feature. As described in the Nuxt configuration documentation (https://nuxt.com/docs/api/nuxt-config#sharedprerenderdata), this can help share payload data between pages that are prerendered, potentially reducing duplicate requests.
5. Refactor your composables:
Consider restructuring your composables to have a single source of truth for the transactions data. You could create a base composable that fetches the transactions, and then have composables A and B extend or use this base composable.
Remember, when using useAsyncData
in composables, it's crucial to follow the guideline mentioned in the Stack Overflow post (https://stackoverflow.com/questions/77949232): avoid using await
before calling a composable. This can lead to errors when multiple useAsyncData
calls are made.
If these suggestions don't fully resolve your issue, you might need to take a closer look at how your composables are structured and how they're being used in your components. The ideal solution would be to have a single source of truth for your transactions data that both composables can reliably access without triggering duplicate requests.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@457147380479950848> Kapa.ai is still learning and improving, please let me know how I did by reacting below.