I have quite a simple code, where I call getData() function onMounted and than I call this function on some emited events. getData function just call useApi composable. But every time I call getData() function the data are fetched more and more times (If I call getData 6 times i get 6 calls at once). Wierd thing is that the function is called just once (when I put for example console.log in it it is called once, but data fetch is stacking calls). This is how it looks like – first component mounted = data fetched once, first emit call = data fetched twice, second emit = data fetched three times:
![Stacking calls](https://i.sstatic.net/yi8qqv0w.png)
The code:
<template>
<PageSection title="Uživatelé" :footerLink="{to: '#', text: 'Administrace uživatelů'}">
<DataTable :isLoading="isLoading" :columns="columns" :pageSize="query.pageSize" :pagination="users.pagination" @pageSizeChange="handlePageSizeChange" @search="handleSearch" @pageChange="handlePageChange">
<tr v-for="user in users.data" :key="user._id">
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
<div>
{{ user.email }}
</div>
<div class="text-[.65rem]">
{{ user._id }}
</div>
</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
<span v-for="role in user.roles">{{ role.name }}</span>
</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ new Date(user.createdAt).toLocaleDateString(undefined, dateOptions) }}</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ new Date(user.updatedAt).toLocaleDateString(undefined, dateOptions) }}</td>
</tr>
</DataTable>
<div v-if="users.error">Error</div>
</PageSection>
</template>
<script setup>
definePageMeta({
title: 'Administrace'
})
const columns = ['Uživatel', 'Role', 'Vytvořeno', 'Změněno']
const users = ref([])
const isLoading = ref(true)
const apiUrl = '/api/v1/private/users'
const query = ref({page: 1, pageSize: 10, search: ''})
onMounted(async () => {
await getData()
})
const getData = async () => {
users.value = []
isLoading.value = true
users.value = await useApi(apiUrl, {
method: 'GET',
query: query
})
isLoading.value = false
}
const handlePageSizeChange = async (newPageSize) => {
query.value = {...query.value, pageSize: newPageSize}
await getData()
}
const handlePageChange = async (pageClicked) => {
query.value = {...query.value, page: pageClicked}
await getData()
}
const handleSearch = async (searchQuery) => {
query.value = {...query.value, search: searchQuery}
await getData()
}
const dateOptions = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
seconds: 'numeric'
}
</script>
useApi composable:
const { refreshToken } = useAuthStore()
var pagination = {}
var error = null
export const useApi = async (url , options) => {
const { data, error } = await useFetch(`http://localhost:3001${url}`, {...options, credentials: 'include', retry: 1, retryStatusCodes: [401],
async onResponse({ request, response, options }) {
pagination = {
recordsTotal: response.headers.get('X-Records-Total'),
pageSize: response.headers.get('X-Page-Size'),
pageCurrent: response.headers.get('X-Page-Current'),
pageTotal: response.headers.get('X-Page-Total'),
linkNextPage: response.headers.get('X-Link-Next-Page'),
linkPreviousPage: response.headers.get('X-Link-Previous-Page'),
linkLastPage: response.headers.get('X-Link-Last-Page')
}
},
async onResponseError({request, response, options}){
if (response.status === 401 && response._data.authenticationToken) {
await refreshToken(response._data.authenticationToken)
return
} else if (response.status === 401){
console.log('Přihlášení vypršelo')
window.location.reload()
}
throw response
},
async onRequest({ request, options }) {
options.headers = options.headers || {};
options.headers.accept = 'application/json';
const { authenticationToken } = useAuthStore()
if (authenticationToken) {
options.headers.authorization = `Bearer ${authenticationToken}`;
}
},
async onRequestError({ request, options, error }) {
console.log('[fetch request error]')
}
})
return {
data: data,
pagination: pagination,
error: error
}
}
Can someone tell me, what am I missing?