Minseven
Minseven

Reputation: 142

useFetch of Nuxt 3 sends same request during refresh instead of updating URL

I try to do a simple thing: At route change, refetch data.

Here is my link:

<li v-for="category in categories" :key="category.id" class="mb-1">
  <NuxtLink :to="{ query: { cat: category.slug } }">
    {{category.title}}
  </NuxtLink>
</li>

And my request:

<script setup>
const route = useRoute()

const { data:categories } = await useFetch('http://127.0.0.1:8000/api/tasks/category/', {
  key: route.fullPath, 
  initialCache: false
})
const { data:tasks, refresh } = await useFetch(`http://127.0.0.1:8000/api/tasks/?cat=${route.query.cat}`, {
  key: `tasks:${route.query.cat}`, 
  initialCache: false
})

watch(() => route.query.cat, () => refresh())

</script>

So, at click, url is well changed:

http://localhost:3000/tasks?cat=category1
http://localhost:3000/tasks?cat=category3
http://localhost:3000/tasks?cat=category2

But requests are the same (from Django DRF backend):

GET http://127.0.0.1:8000/api/tasks/?cat=category1
GET http://127.0.0.1:8000/api/tasks/?cat=category1
GET http://127.0.0.1:8000/api/tasks/?cat=category1

It seems that it keeps the first category, even with initialCache: false

Upvotes: 4

Views: 8933

Answers (3)

Abdelrahman Ismail
Abdelrahman Ismail

Reputation: 144

This solution works if you have multiple query params.

For example, working with Vuetify Server Side Data Tables

const query = reactive({
  limit: 1,
  page: 1,
});


const {
  data: integrationsConnections,
  refresh,
} = await useFetch("GET", "/resources", { query });


const handleDataChange = (params) => {
  query.page = params.page;
  query.limit = params.itemsPerPage;

  refresh();
};

Upvotes: -1

Stefan
Stefan

Reputation: 126

useFetch is "freezing" the API URL, the changes you make to the string directly will not be reflected. If you want to add parameters to your API URL, as an alternative to using a function, you can use the query option of useFetch. This option is reactive, that is when the ref with your route is changing, the query will reflect this update.

For your case, this will work:

const cat = ref('your_value')

const { data:tasks, refresh } = await useFetch('http://127.0.0.1:8000/api/tasks', {
  query: { cat }
})

This results in http://127.0.0.1:8000/api/tasks?cat=your_value

You don't need to mess with the key option, as the key will be auto generated, and you can also leave the cache alone.

The query option is not well documented yet, as discussed in this nuxt issue. I've created a pull request on nuxt/framework to have it reflected in the documentation. Please see a full explanation below:

Using the query option, you can add search parameters to your query. This option is extended from unjs/ohmyfetch and is using ufo to create the URL. Objects are automatically stringified.

const param1 = ref('value1')
const { data, pending, error, refresh } = await useFetch('https://api.nuxtjs.dev/mountains',{
    query: { param1, param2: 'value2' }
})

This results in https://api.nuxtjs.dev/mountains?param1=value1&param2=value2

Upvotes: 7

some-user
some-user

Reputation: 4934

As mentioned in the comments, the URL should not be provided as string

const { data:tasks, refresh } = await useFetch(`http://127.0.0.1:8000/api/tasks/?cat=${route.query.cat}`, {
  key: `tasks:${route.query.cat}`, 
  initialCache: false
})

but as a function returning a string:

const { data:tasks, refresh } = await useFetch(() => `http://127.0.0.1:8000/api/tasks/?cat=${route.query.cat}`, {
  key: `tasks:${route.query.cat}`, 
  initialCache: false
})

Upvotes: 5

Related Questions