N
Nuxtβ€’11mo ago
Cesar

Repository pattern warning useFetch with Nuxt 3.10

Good morning, In the latest version of Nuxt (3.10) warnings appeared when using useFetch outside of setup. This causes me problems because I have an architecture split via the pattern repository and there is no reason for this to give me warnings. (PR #25071) Here is an example of splitting that I have: index.vue file: try { data.value = await Repository.taxModule.taxClass.getAll({ ...defaultFetchTaxClassParams, ...options, }) } catch(e:any) { setRequestError(e) } This method calls a utility class acting as a pass-through Method called: static async getAll( getTaxClassesOptions: API_taxClass_getTaxClassesOptions, ): Promise<ResultList<TaxClass>> { return await BaseRepository.getAllFactory<TaxClass>({ apiUrl: TaxClass.getApiUrlPrefix(), options: getTaxClassesOptions, adapter: TaxClassApiAdapters.formatTaxClassesResponse, }) } And finally the getAllFactory method (calling my useApiFetch component) static async getAllFactory<T>({ apiUrl, options, adapter, }: { apiUrl: string options?: any adapter: (data: any, options?: any) => ResultList<T> }): Promise<ResultList<T>> { const url = ApiQuery.buildQueryString(apiUrl, options) let response: unknown await useApiFetch(url) .catch((error) => { throw error }) .then((res) => { response = res }) return adapter(response, options) } My useApiFetch is currently a composable allowing me to wrap the standard useFetch and add my token and other options What should I change to keep this architecture while no longer having the warnings? If I replace the useFetch in my composable with a $fetch, the SSR no longer happens at all.. Thanks in advance
27 Replies
Cesar
CesarOPβ€’11mo ago
Up please
manniL
manniLβ€’11mo ago
Would be easier to provide a running reproduction πŸ™‚
Cesar
CesarOPβ€’11mo ago
This requires a lot of additional code and my api will not be accessible :/ What do you recommend in very large applications for code sharing at the API call level? (while keeping my custom composable which wrap useFetch to add the token in particular) ? This warning can be disabled ?
Cesar
CesarOPβ€’11mo ago
Hello ! I made a repro to illustrate (in a very simplified way the problems following the update) The problem will occurs when you click the button to make another call. I have this kind of case in my application hundreds of times (whether to apply a filter, to make an API call after an action..) I also need to keep my wrapper at useFetch to add my token (here I left it empty but it's to show my archi) Thanks in advance ! https://stackblitz.com/edit/github-pgv3r7?file=app.vue
Anthony Ruelle
StackBlitz
Nuxt 3.10 - useFetch warning - StackBlitz
Create a new Nuxt project, module, layer or start from a theme with our collection of starters.
manniL
manniLβ€’11mo ago
@Cesar You technically do a version of the mistake I show in my video, but "more complex" πŸ˜„ https://www.youtube.com/watch?v=njsGVmcWviY
Alexander Lichter
YouTube
You are using useFetch WRONG! (I hope you don't)
πŸ’ͺ🏻 useFetch is a mighty composable to fetch data in your Nuxt.js application. It can do so many things, from updating state to refreshing calls easily and even data caching is possible. But often I see that people misuse useFetch because it is so tempting to use all the features, even when you shouldn't. In this video I show the most common mist...
Cesar
CesarOPβ€’11mo ago
Thank you for your feedback, and an additional subscription πŸ˜‰ Wow I'm going to have to rethink a lot of things to fix this. If I understood correctly, when I need to make a call with immediate rendering (SSR) I must go through the useFetch, in all other cases $fetch ? Would it be okay to pass a boolean to my functions to say to use useFetch or $fetch depending on where the calls are made ?
manniL
manniLβ€’11mo ago
you are welcome! Thanks for the sub πŸ™ Hmm, not exactly. useFetch is also fine on the client. The thing is though: You don't want to call composables without the "right context" So you don't want to call useFetch in a click handler instead, you would want to use fetch there
Would it be okay to pass a boolean to my functions to say to use useFetch or $fetch depending on where the calls are made ?
From an architectural point, these are two very different things (function vs. composable). I'd not do that instead, use your repository pattern fully based on $fetch, then use useAsyncData to call the pattern πŸ™‚
Cesar
CesarOPβ€’11mo ago
The problem is that if I use $fetch in my wrapper, I will no longer have a call that will be made in SSR? I don't really see how I could use useAsyncData to call the pattern Really thank you for taking the time to answer me
manniL
manniLβ€’11mo ago
the idea would be to do sth. like useAsyncData(() => MyRepositoryHere.get('/url/') which will be "under the hood": useAsyncData(() => $fetch('/url'/, {...}))
Cesar
CesarOPβ€’11mo ago
Okay, I see the idea. I will try to set this up today. I'll tell you what happens πŸ™‚
Cesar
CesarOPβ€’11mo ago
I tried to update the stackblitz to follow your recommendations but I have 2 problems: - The first call is made on the client side, with the old way they were made on the server side - Hydration concerns due to differences https://stackblitz.com/edit/github-pgv3r7?file=composables%2FuseApiFetch.ts,api%2Fbase.ts,app.vue Where did I go wrong ?
StackBlitz
Nuxt 3.10 - useFetch warning - StackBlitz
Create a new Nuxt project, module, layer or start from a theme with our collection of starters.
manniL
manniLβ€’11mo ago
@Cesar I'll release a video about it tomorrow πŸ˜„ As I got quite some requests on that πŸ˜„
Cesar
CesarOPβ€’11mo ago
Oh great, I can't wait to see this! Hoping to get over this problem very soon πŸ€—
manniL
manniLβ€’11mo ago
Alexander Lichter
YouTube
Custom $fetch and Repository Pattern in Nuxt 3
πŸ’» The repository pattern is a popular way to abstract your API calls away and provide a descriptive way to retrieve or send data. But how would you implement it in Nuxt? And should you use composables or $fetch for it? This video will give answers to all the questions! Key points: πŸŽ›οΈ Implementing the repository pattern in Nuxt πŸ”› Creating our ow...
manniL
manniLβ€’11mo ago
(live at 3pm)
Cesar
CesarOPβ€’11mo ago
Yeahhhh
Cesar
CesarOPβ€’11mo ago
No description
Cesar
CesarOPβ€’11mo ago
Hello @manniL / TheAlexLichter it's me again πŸ™‚ Thank you again for your video, it’s very interesting! I have a question because in my implementation I also transform the data before returning it. How to do with the implementation so that the returned data is well transformed?
Cesar
CesarOPβ€’11mo ago
Moreover, using the example of the video, I still have my problems with the warnings :/ I updated the stackblitz to show the problem (on button click) https://stackblitz.com/edit/github-pgv3r7?file=app.vue
Anthony Ruelle
StackBlitz
Nuxt 3.10 - useFetch warning - StackBlitz
Create a new Nuxt project, module, layer or start from a theme with our collection of starters.
manniL
manniLβ€’11mo ago
because you still use composables in your handler functions πŸ™‚ try
<template>
<div>
<button @click="fetchOtherTodo">Fetch other todo</button>
<div>{{ localTodo ?? 'no todo' }}</div>
</div>
</template>

<script setup lang="ts">
import { Todo } from './entities/todo';

const { $api } = useNuxtApp();
const todoRepo = repository($api);

const localTodo = useState<Todo | null>('todos', () => null);
const fetchTodo = async (todoId: number) => {
try {
const data = await todoRepo.getOne(todoId)
localTodo.value = data;
} catch (e: any) {
console.error(e);
}
};

const fetchOtherTodo = async () => {
const randomId = Math.floor(Math.random() * 10) + 2;
await fetchTodo(randomId);
};

await fetchTodo(1);
</script>
<template>
<div>
<button @click="fetchOtherTodo">Fetch other todo</button>
<div>{{ localTodo ?? 'no todo' }}</div>
</div>
</template>

<script setup lang="ts">
import { Todo } from './entities/todo';

const { $api } = useNuxtApp();
const todoRepo = repository($api);

const localTodo = useState<Todo | null>('todos', () => null);
const fetchTodo = async (todoId: number) => {
try {
const data = await todoRepo.getOne(todoId)
localTodo.value = data;
} catch (e: any) {
console.error(e);
}
};

const fetchOtherTodo = async () => {
const randomId = Math.floor(Math.random() * 10) + 2;
await fetchTodo(randomId);
};

await fetchTodo(1);
</script>
Cesar
CesarOPβ€’11mo ago
With your proposal I no longer have the warning, however the first call is made on the client side whereas previously it was done on the server side :/
manniL
manniLβ€’11mo ago
this is made on both right now I'd use useAsyncData instead there πŸ˜„ (with a parameter + watch) for example
Cesar
CesarOPβ€’11mo ago
I also tried with useAsyncData and either I got the warning or the first call is only made on the client side I must really be doing something wrong ^^
manniL
manniLβ€’11mo ago
let me show you πŸ™‚
Cesar
CesarOPβ€’11mo ago
wow it works well with this implementation, awesome! I'm going to look into this and try to implement it on a small part of my application! A big thank you πŸ€—
manniL
manniLβ€’11mo ago
no problem!
Want results from more Discord servers?
Add your server