Reputation: 365
I have a custom hook to fetch data that is looking like this:
import { reactive } from 'vue';
import axios from 'axios';
interface State {
isLoading: boolean;
isError: boolean;
errorMessage: string,
data: object|null
}
export default function useAxios(url: string, data: object) {
const state = reactive({
isLoading: true,
isError: false,
errorMessage: '',
data: null
}) as State;
const fetchData = async () => {
try {
const response = await axios({
method: 'GET',
url: url, // '/test_data/campaign.json'
data: data
});
state.data = response.data;
} catch (e) {
state.isError = true;
state.errorMessage = e.message;
} finally {
state.isLoading = false;
}
};
return {
toRefs(state), //TS complains over "Parameter 'state' implicitly has an 'any' type." But it's already typed in the above???
fetchData
};
}
Im trying to use this in my custom component, but I keep getting that data is undefined, even though I can see the data if I do a console.log() in my custom hook where im calling the endpoint and logging the response...
Im trying to use it like this
setup() {
const state = reactive({
data: null
});
const {data, isLoading, fetchData} = useAxios(
'/test_data/campaign.json',
{}
);
const getCampaignData = async () => {
await fetchData();
console.log('data', data);
state.data = data;
};
onMounted(() => {
getCampaignData();
});
return {
data: state.data
};
}
What am I doing wrong here? In the hook, response.data has the data from the JSON file, but when calling the data from the hook in my component, it's null ?
Upvotes: 2
Views: 3490
Reputation: 1
In composable function try to not spread the state since it loses its reactivity, you could use toRefs
to return a reactive ref :
import {reactive,toRefs} from 'vue';
import axios from 'axios';
export default function useAxios(url: string, data: object) {
....
return {
...toRefs(state),
fetchData
}
}
then in your component call that composable function outside the getCampaignData
function like :
import {reactive,toRefs,onMounted} from 'vue';
setup() {
const state = reactive({
data: null
});
const { data, isLoading, fetchData } = useAxios(
'/test_data/campaign.json',
{}
);
const getCampaignData = async () => {
await fetchData();
state.data = data.value;
};
onMounted( ()=>{
getCampaignData();
})
return {
...toRefs(state)
};
}
Upvotes: 1