Reputation: 327
I have a very normal Vuex store file and here is the code:
//store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
loading: true,
companyBasicInfo: [
]
},
mutations: {
getCompanyBasicInfo: (state, res) => {
state.companyBasicInfo.push(res);
},
changeLoadingStatue: (state, loading) => {
state.loading = loading;
}
},
actions: {
getCompanyBasicInfo: context => {
// HERE IS MY AXIOS REQUESTS
}
}
});
I am writing my axios request in getCompanyBasicInfo() actions and everything works perfectly.
Separate my AXIOS requests in another file and just call them in my store.js file just to reduce my store.js file..
I have tried to create file called requests.js and write this code in it:
import axios from 'axios';
export default GET_COMPANY_DETAILS = () => {
setTimeout(() => {
axios.get('http://localhost:3000/companies/show/trade key egypt').then((res) => {
context.commit('getCompanyBasicInfo', res.data);
context.commit('changeLoadingStatue', false);
}).catch(e => {
console.log(e);
});
}, 3000);
};
And then trying to import them in my store.js file
import requests from './requests';
Whenever I try to write requests.GET_COMPANY_DETAILS();
in my getCompanyBasicInfo()
action I couldn't access the method in the requests.js
file.
Uncaught ReferenceError: GET_COMPANY_DETAILS is not defined
in console
Upvotes: 4
Views: 3451
Reputation: 17430
Since you're using export default GET_COMPANY_DETAILS
, when you import requests
, it is the GET_COMPANY_DETAILS
function.
So you could call requests()
directly.
See the MDN documentation on export
to see all the possibilities.
That being said, the proper way to export an API would be:
// api.js
import axios from 'axios';
// create an axios instance with default options
const http = axios.create({ baseURL: 'http://localhost:3000/' });
export default {
getCompanyDetails(tradeKey) {
// then return the promise of the axios instance
return http.get(`companies/show/${tradeKey}`)
.catch(e => {
// catch errors here if you want
console.log(e);
});
},
anotherEndpoint() {
return http.get('other/endpoint');
}
};
You can export a default
API like I did, or even both named and default export.
export function getCompanyDetails(tradeKey){ /*...*/ }
export default { getCompanyDetails }
Then, in your store:
import api from './api';
// ...
actions: {
getCompanyBasicInfo({ commit }, key) {
// It's important to return the Promise in the action as well
return api.getCompanyDetails(key).then(({ data }) => {
commit('getCompanyBasicInfo', data);
commit('changeLoadingStatue', false);
});
}
}
The store related code still needs to be within your actions.
I've written an answer with examples on axios-middleware and axios-resource which helps create single responsibility modules.
You can handle errors in a middleware, while focusing the endpoint configuration within resource classes.
Upvotes: 4
Reputation: 8060
I suggest you structure your code according to suggested application structure in Vuex documentation.
That will give you nice separation of concerns and make your store.js nice and lean.
Then, export the function instead of exporting it as default. In future, you may want to export multiple functions from requests.js
.
E.g.
import axios from 'axios';
export function getCompanyDetails() {
setTimeout(() => {
axios.get('http://localhost:3000/companies/show/trade key egypt').then((res) => {
context.commit('getCompanyBasicInfo', res.data);
context.commit('changeLoadingStatue', false);
}).catch(e => {
console.log(e);
});
}, 3000);
};
export function someOtherApiMethod() {}
Then, instead of using setTimeout
in GET_COMPANY_DETAILS
, return the promise from Axios itself.
E.g.
export function getCompanyDetails() {
return axios
.get('http://localhost:3000/companies/show/trade key egypt')
.then(res => res.data)
};
Then, use the promise in your action
import { getCompanyDetails } from './requests';
actions: {
getCompanyBasicInfo: context => {
getCompanyDetails().then(() => {
// commit your mutations
});
}
}
Upvotes: 0