To use $http
or $router
in your vuex repository, you will need to use the main vue instance. Although I do not recommend using this, I will add what I recommend after answering the actual question.
In your main.js
or wherever you create your vue instance, for example:
new Vue({ el: '#app', router, store, template: '<App><App/>', components: { App } })
or something similar, you can also add vue-router
and vue-resource
plugins.
After making a small change:
export default new Vue({ el: '#app', router, store, template: '<App><App/>', components: { App } })
Now I can import it into vuex repositories as follows:
//vuex store: import YourVueInstance from 'path/to/main' checkMovieStore(state) { const routerMovieId = YourVueInstance.$route.params.movieId; const storeMovieId = state.movieDetail.movie_id; if (routerMovieId != storeMovieId) { let url = "http://dev.site.com/api/movies/movie-list/" + routerMovieId + "/"; YourVueInstance.$http.get(url) .then((response) => { state.movieDetail = response.data; }) .catch((response) => { console.log(response) }); } }
and as Austio's answer , this method should be action
, since mutations
not meant to handle async.
Now let's get to the recommended way to do this.
Your component
can access route params
and provide its action
.
methods: { ...mapActions({ doSomethingPls: ACTION_NAME }), getMyData () { this.doSomethingPls({id: this.$route.params}) } }
Then action
makes a call through an abstract API service file ( read plugins
)
[ACTION_NAME]: ({commit}, payload) { serviceWhichMakesApiCalls.someMethod(method='GET', payload) .then(data => {
Your actions
do some asynchronous task and provide a mutation
result.
serviceWhichMakesApiCalls.someMethod(method='GET', payload) .then(data => {
mutations
should be the only ones who can change your state
.
[SOME_MUTATION]: (state, payload) { state[yourProperty] = payload }
Example A file containing a list of endpoints may be required if you have different deployment steps that have different api endpoints, such as: test, staging, production, etc.
export const ENDPOINTS = { TEST: { URL: 'https://jsonplaceholder.typicode.com/posts/1', METHOD: 'get' } }
And the main file that implements Vue.http
as a service:
import Vue from 'vue' import { ENDPOINTS } from './endpoints/' import { queryAdder } from './endpoints/helper' function transformRequest (ENDPOINT, query, data) { return (ENDPOINT.METHOD === 'get') ? Vue.http[ENDPOINT.METHOD](queryAdder(ENDPOINT.URL, query)) : Vue.http[ENDPOINT.METHOD](queryAdder(ENDPOINT.URL, query), data) } function callEndpoint (ENDPOINT, data = null, query = null) { return new Promise((resolve, reject) => { transformRequest(ENDPOINT, query, data) .then(response => { return response.json() }) .then(data => { resolve(data) }) .catch(error => { reject(error) }) }) } export const APIService = { test () { return callEndpoint(ENDPOINTS.TEST) }, login (data) { return callEndpoint(ENDPOINTS.LOGIN, data) } }
RequestAdder in case this is important, I used this to add params to the url.
export function queryAdder (url, params) { if (params && typeof params === 'object' && !Array.isArray(params)) { let keys = Object.keys(params) if (keys.length > 0) { url += `${url}?` for (let [key, i] in keys) { if (keys.length - 1 !== i) { url += `${url}${key}=${params[key]}&` } else { url += `${url}${key}=${params[key]}` } } } } return url }