feat(nuxt): add `immediate` option for `useAsyncData` and `useFetch`
🔗 Linked issue
- #5256
❓ Type of change
- [x] 📖 Documentation (updates to the documentation or readme)
- [ ] 🐞 Bug fix (a non-breaking change that fixes an issue)
- [x] 👌 Enhancement (improving an existing functionality like performance)
- [x] ✨ New feature (a non-breaking change that adds functionality)
- [ ] ⚠️ Breaking change (fix or feature that would cause existing functionality to change)
📚 Description
If the newly added option immediate is set to false (defaults to true) it will prevent the request from firing immediately.
It also provides a new function execute which can be used to trigger the request manually.
Without this change, useAsyncData and useFetch need to be wrapped inside a function in order to call them on user interaction. With this change, no wrapping is necessary, and the request can be triggered manually via execute, much like: https://vueuse.org/core/usefetch/#prevent-request-from-firing-immediately
Resolves #5256
📝 Checklist
- [x] I have linked an issue or discussion.
- [x] I have updated the documentation accordingly.
Deploy Preview for nuxt3-docs ready!
| Name | Link |
|---|---|
| Latest commit | c40980e9b96c107dd53b5c61b47fde863bb5d676 |
| Latest deploy log | https://app.netlify.com/sites/nuxt3-docs/deploys/63186374b7f1e00008b93ce8 |
| Deploy Preview | https://deploy-preview-5500--nuxt3-docs.netlify.app |
| Preview on mobile | Toggle QR Code...Use your smartphone camera to open QR code link. |
To edit notification comments on pull requests, go to your Netlify site settings.
Hi @Vl4dimyr and thanks for the PR. It for sure makes sense to make a lazy executed version of asyncData/fetch but I'm afraid it might introduce behavior inconsistencies if we directly introduce this option directly for existing useAsyncData and useFetch.
(eg: What happens after the first execution? Should we watch and refetch on refs? Does it make sense if usage is intended to be manual by watcher? Is it needed to be in SSR payload when execution is manual?).
What do you think if we introduce a new composable such as useFetcher with simplified implementation and clear usage?
Thinking about the use case mentioned in the https://github.com/nuxt/nuxt.js/issues/14333, to me an immediate option would be particularily useful for declaring (at the top level) and freezing the whole data fetching composable until one wishes to make use of it.
Should we watch and refetch on refs?
What about introducing another boolean option called immediateWatch? I am sure both use cases (with watchers initialised immediately and not) are important to cover and would find their supporters.
Going even further, if the immediate option was included to the currently existing data fetching composables, I would consider renaming refresh to something that wouldn't imply rerunning the composable (as if it already run at least once), such as trigger/execute. This would be indeed a breaking change, but less misleading regardless of the immediate option's value.
On the other hand, the approach outlined by @pi0 which is introducing a new composable might be a better idea. I really struggle to have preference of one solution over the other.
I'm not sure what would be better between introducing a new useFetcher composable or just merging this PR, but a composable with the same signature as useAsyncData that does not auto-fetch the data is definitely needed.
My use-case would be passing AsyncData objects from pages to components : the pages are responsible for defining API routes, transforms, etc and the components make use of data, pending, etc. I want the components receiving the AsyncData as a prop to be responsible for firing the requests (using refresh), but I currently do not see a way to get the AsyncData in the first place without firing the request first.
What can I do to help move this PR closer to merging ?
@pcouy Would you please share your use case in linked issue nuxt/nuxt.js#14090? A code example or sandbox would be nice 🙏🏼
As I mentioned earlier, such functionality makes sense but it is not what currently useAsyncData use is intended to.
Sorry, it took long to be back on this feature. I was thinking more, introducing more composables for data fetching would be ultimately confusing more even. And adding this flag is not adding much overhead and covers use cases.
I've made a rebase added basic tests and a refactor that refrash and execute are now aliases (we might deprecate refrash if finally it makes sense until 3.0.0 release). When await data.execute() is used, it does make more sense to me it always skips payload cache. _initial is mainly an internal option to reuse payload on hydration and execute is a manual caller. It is up to developer to decide when it should be called.
(BTW nothing is set on stone. Feedback is more than welcome until we reach 3.0.0 to refine API)