I just use the catch. The same thing I was using before I switched to vuex. It's probably the most universal and well documented solution and lets me continue to insert my errors into the html of the components like I was doing before. It also lets me continue to use my loading = true, loading = false html animation.
So I end up with 3 state properties, data, error, and loading. It seems to work for me. Your mileage may vary. I am also using vuex modules and namespacing but here is a simplified example without that
//somevuexstore.js
actions: {
fetchData(context) {
axios
.get("api/someendpoint")
.then(response => {
context.commit('loading')
context.commit('organizations', response.data)
}).catch(error => {
console.log(error.response.data.message || error.message)
context.commit('error', error)
});
},
mutations: {
organizations(state, data) {
return state.organization = data
},
error(state, data) {
return state.error = data
},
loading(state) {
return state.loading = false
},
state= {
organization: [],
error: '',
loading: true
}
Then in my component.vue it's very similar to the way I was doing it before, just with the added computed properties.
computed: {
...mapState({
getError: 'error',
getLoading: 'loading',
getAllOrg: 'organization',
}),
}
mounted() {
this.$store.dispatch('fetchData')
}
And my html would be stuff like this.
<tr v-for="value in getAllOrg" :key="value.id">
<td>{{ value.id }}</td>
<td>{{ value.email }}</td>
<td>{{ value.name }}</td>
<td>{{ value.['created-at'] | formatDate }}</td>
</tr>
I insert the error messages where appropriate
<div v-if="getError" class="error">
<p>{{ getError }}</p>
</div>
For loading animation I use vue spinners package inserted into html where appropriate.
<div v-if="getLoading" style="height:37px;">
<p>
<bar-loader class="custom-class" color="#c2c2c2"
getLoading="getLoading"
:width="130"></bar-loader>
</p>