Before I was getting movie detail from the component's script. The function first check whether the movie ID of the store is same as of the route's param movie ID. If its same then don't get the movie from the server API, or else get the movie from the server API.
It was working fine. But now I am trying to get the movie details from the store's mutation. However I am getting error
Uncaught TypeError: Cannot read property '$route' of undefined
How to use vue-router ($route)
to access the params and vue-resource ($http)
to get from the server API in vuex store?
store.js:
export default new Vuex.Store({
state: {
movieDetail: {},
},
mutations: {
checkMovieStore(state) {
const routerMovieId = this.$route.params.movieId;
const storeMovieId = state.movieDetail.movie_id;
if (routerMovieId != storeMovieId) {
let url = "http://dev.site.com/api/movies/movie-list/" + routerMovieId + "/";
this.$http.get(url)
.then((response) => {
state.movieDetail = response.data;
})
.catch((response) => {
console.log(response)
});
}
},
},
});
component script:
export default {
computed: {
movie() {
return this.$store.state.movieDetail;
}
},
created: function () {
this.$store.commit('checkMovieStore');
},
}
So a few things, the $store and $route are properties of the Vue instance, which is why accessing them inside of Vuex instance is not working. Also, mutations are synchonous what you need are actions
Mutations => A function that given state and some arguments mutates the state
Action => Do async things like http calls and then commit results to a mutation
So create an action that dispatches the http. Keep in mind this is pseudocode.
Now your created function dispatches the checkMovieStore action with the id, which does the http call, once that is complete it updates the store with the value.
To use
$http
or$router
in your vuex store, you would need to use the main vue instance. Although I don't recommend using this, I'll add what I recommend after answering the actual question.In your
main.js
or wherever you are creating your vue instance like:or something similar, you might also have added the
vue-router
andvue-resource
plugins too.Doing a slight modification to this:
I can now import it in vuex stores like so:
and as the answer by Austio goes, this method should be an
action
asmutations
are not designed to handle async.Now coming to the recommended way of doing it.
Your
component
can access theroute params
and provide it to theaction
.The
action
then makes the call through an abstracted API service file (readplugins
)Your
actions
do some async job and provide the result to amutation
.Mutations
should be the only ones to modify yourstate
.Example A file which contains a list of endpoints, you might need it if you have different stages of deployment which have different api endpoints like: test, staging, production, etc.
And the main file which implements
Vue.http
as a service:The queryAdder in case it is important, I was using this to add params to the url.