Reputation: 167
I'm trying to build up my API service in my VueJS application by using Vuex. I'm in the process of refactoring some stuff to centralize error handling, clean-up, etc. The issue I'm running into is properly chaining Promises through my function calls.
At the root level, I have a BaseService class, which simply make API requests using AXIOS (not full class):
export abstract class BaseService {
protected readonly API: AxiosInstance; // Full init left out
protected deleteItem(url: string): Promise<any> {
return new Promise((resolve, reject) => {
this.API.delete(url)
.then((response: any) => {
resolve(response);
})
.catch((error: any) => {
this.handleError(error); // Local function that logs error
reject(error);
});
});
}
}
Then I have one layer above which managers different features of the API by assembling the request URL and handling the data:
class CompanyService extends BaseService {
private constructor() {
super();
}
public delete(id: number): Promise<any> {
return this.deleteItem(`${this.baseUrl}/api/companies/${id}`);
}
}
Then in my Vuex action I'm calling the companyService delete function:
const action = {
COMPANY_DELETE(context: any, id: number) {
return new Promise((resolve, reject) => {
companyService // Instance of CompanyService
.delete(id)
.then((response: any) => {
console.log(response); // This logs successfully
resolve(response);
})
.catch((error: any) => {
console.log(error); // This logs successfully
reject(error);
});
});
}
};
The two console logs complete successfully as indicated by my comments. This issue comes in when I get to the component which invokes this action:
this.$store
.dispatch("company/COMPANY_DELETE", company.id) // Namespaced
.then((response: any) => {
console.log(response); // Never gets called
})
.catch((error: any) => {
console.log(error); // Never gets called
});
Those two console logs are never called. What am I doing wrong here?
Upvotes: 2
Views: 4725
Reputation: 167
What ended up working was to remove the extra Promise like Void Ray said. However, in my particular use-case I also need to support error propagation. So the below action contains the fixes that I needed to make.
const action = {
COMPANY_DELETE(context: any, id: number) {
return companyService // Instance of CompanyService
.delete(id)
.then((response: any) => {
console.log(response);
})
.catch((error: any) => {
console.log(error);
throw error; // Needed to continue propagating the error
});
},
};
Upvotes: 3
Reputation: 10199
Small example to demonstrate an action with axios without an extra promise wrap...
const store = new Vuex.Store({
state: {
followers: 0
},
mutations: {
updateFollowers(state, followers){
state.followers = followers;
}
},
actions: {
getFollowers({commit}) {
return axios.get('https://api.github.com/users/octocat').then( (response) => {
commit("updateFollowers", response.data.followers);
return "success!!!";
});
}
}
})
Vue.component('followers', {
template: '<div>Followers: {{ computedFollowers }}</div>',
created () {
this.$store.dispatch('getFollowers').then( (result) => {
console.log(result);
});
},
computed: {
computedFollowers() {
return store.state.followers;
}
}
});
const app = new Vue({
store,
el: '#app'
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="app">
<followers></followers>
</div>
Upvotes: 3