I'm currently trying out some of the latest vue version and features (3.2).
I've created a useFetch composable to reuse some logic (it's based on the vue documentation)
useFetch.js
import { ref } from 'vue'
import axios from 'axios';
const apiClient = axios.create({
baseURL: process.env.VUE_APP_API_ENDPOINT,
withCredentials: false,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
timeout: 10000,
});
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
const isLoading = ref(true);
apiClient({ method, url, data: body })
.then((response) => (data.value = response.data))
.catch((err) => (error.value = err))
.finally(() => isLoading.value = false)
return { data, error }
}
I'm using the useFetch composable in a component to fetch companies from the backend. The data I'm getting back is rough so I want to reformat it using a computed (That was the way I did it when using vue 2)
CompanyList.vue
<script setup>
import { computed } from 'vue';
import useFetch from '@/composables/useFetch';
import { formatEmail, formatPhone, formatEnterpriseNumber } from '@/utils/formatters';
const { data, isLoading, error } = useFetch('get', '/companies');
const companies = computed(() =>
data.companies?.map((company) => ({
id: `#${company.id}`,
name: `${company.legal_entity_type} ${company.business_name}`,
enterprise_number: formatEnterpriseNumber(company.enterprise_number),
email: formatEmail(company.email),
phone: formatPhone(company.phone),
}))
);
</script>
<template>
<div v-if="isLoading">Loading...</div>
<div v-else-if="error">Oops! Error encountered: {{ error }}</div>
<div v-else-if="companies">
Companies:
<pre>{{ companies }}</pre>
</div>
<div v-else>No data :(</div>
</template>
When using Companies
inside the template tags it stays null
. I've checked and data
has a companies property of the type Array with data in it.
Anyone an idea how to handle this?
CodePudding user response:
I think the issue may be due to use of ref
. Try using reactive
for data instead of ref
export function useFetch(url) {
const data = reactive(null);
const error = ref(null);
const isLoading = ref(true);
apiClient({ method, url, data: body })
.then((response) => (data = response.data))
.catch((err) => (error.value = err))
.finally(() => isLoading.value = false)
return { data, error }
}
To use ref
, you would need to access the value via ref.value
. Also, ref
is not the best choice for objects and arrays as it was meant for primitive data types. to use ref
you can
const companies = computed(() =>
data.value?.companies?.map((company) => ({
id: `#${company.id}`,
name: `${company.legal_entity_type} ${company.business_name}`,
enterprise_number: formatEnterpriseNumber(company.enterprise_number),
email: formatEmail(company.email),
phone: formatPhone(company.phone),
}))
);
note the use of ?.
after value, which is required since the ref is null initially.