I have a Vue Webpack app with Vuex (I am new to both, coming in from the Ember world). I've currently got it setup to use vue-resource with two files like this:
/src/store/api.js
import Vue from 'vue';
import { store } from './store';
export default {
get(url, request) {
return Vue.http
.get(store.state.apiBaseUrl + url, request)
.then(response => Promise.resolve(response.body))
.catch(error => Promise.reject(error));
},
post(url, request) {
return Vue.http
.post(store.state.apiBaseUrl + url, request)
.then(response => Promise.resolve(response))
.catch(error => Promise.reject(error));
},
// Other HTTP methods removed for simplicity
};
I then import the api.js file above into my /src/store/store.js file like this:
import Vue from 'vue';
import Vuex from 'vuex';
import Api from './api';
Vue.use(Vuex);
// eslint-disable-next-line
export const store = new Vuex.Store({
state: {
apiBaseUrl: 'https://apis.myapp.com/v1',
authenticatedUser: null,
},
mutations: {
/**
* Updates a specific property in the store
* @param {object} state The store's state
* @param {object} data An object containing the property and value
*/
updateProperty: (state, data) => {
state[data.property] = data.value;
},
},
actions: {
usersCreate: (context, data) => {
Api.post('/users', data)
.then(response => context.commit('updateProperty', { property: 'authenticatedUser', value: response.body }))
// eslint-disable-next-line
.catch(error => console.error(error));
},
},
});
When I need to create a new user, I simply this.$store.dispatch('usersCreate', { // my data });
in my component. This works just fine but I have a few issues:
What is the right way to go about it? How can I check for the AJAX failure / success state in the component where I dispatch the action? What is the best practice to make API calls when using Vuex?
Your action should return a Promise. Your current code just calls Api.post
without returning it, so Vuex is out of the loop. See the example from Vuex docs for Composing Actions.
When you a return a Promise, the action caller can then follow the then()
chain:
this.$store.dispatch('usersCreate').then(() => {
// API success
}).catch(() => {
// API fail
});
As for organizing your actions, you don't have to put them all in your store.js
file. Vuex supports modules/namespacing. https://vuex.vuejs.org/en/modules.html