Use Plugin inside Vuex module action
-
When using the Vuex modules I was trying to use the axios plugin from inside the actions of this module.
I use the axios plugin with settings the way as described in docs.
I then have namespaced vuex modules, and inside the actions I can’t reach the this.$axiosWhat am I overlooking?
Or am I wrong and do I need to perform my axios calls in my vue files?Axios plugin (axios.js):
import axios from 'axios' export default ({ Vue }) => { //Vue.prototype.$axios = axios Vue.prototype.$axios = axios.create({ baseURL: 'https://api.app.eu' } }) }
Store setup (store/index.js)
import Vue from 'vue' import Vuex from 'vuex' import auth from './module-auth' Vue.use(Vuex) const store = new Vuex.Store({ modules: { auth } }) export default store
Vuex module - index (store/module-auth/index.js)
import state from './state' import * as getters from './getters' import * as mutations from './mutations' import * as actions from './actions' export default { namespaced: true, state, getters, mutations, actions }
Vuex module Auth - actions (store/module-auth/actions.js)
!!This is where this.$axios is not foundimport { Notify, Loading } from 'quasar' /* export const someAction = (state) => { } */ export const doLogin = (state,creds) => { state.commit('LOGIN') let email=creds.email let password=creds.password console.log(this.$axios) return this.$axios .post('/auth/signin', { email, password }) .then(r => { //console.log(r) //localStorage.setItem("token", "JWT"); commit('LOGIN_SUCCESS') return r }) .catch(e => { //console.log(e.response) Notify.create("Error: " + e.response.status) //localStorage.removeItem("token") commit('LOGOUT') return e }) } export const doLogout = (state) => { localStorage.removeItem("token") commit(LOGOUT) }
Trying to dispatch it in one of my vue files:
methods: { login () { this.$store.dispatch("doLogin", { email: this.email, password: this.password }) } },
-
I could add this to the payload of dispatch, but is this the correct aproach?
this.$store.dispatch("auth/doLogin", { email: this.email, password: this.password, that: this })
-
Might be better to just pass in ‘this’,
this.$store.dispatch("auth/doLogin", this)
Then
export const doLogin = (state,that) => { return that.$axios() }
-
None of the above ways of doing it seems like a good alternative.
If you are using vuex seems that you shouldn’t use plugins at all, at least not for things that should be used from actions. Having logic both on components and store does not seems like a good idea. -
You can use this simple plugin https://github.com/imcvampire/vue-axios. (This wrapper bind axios to Vue or this if you’re using single file component)
Then you can use axios like this :
import Vue from 'vue' import { Notify, Loading } from 'quasar' /* export const someAction = (state) => { } */ export const doLogin = (state,creds) => { state.commit('LOGIN') let email=creds.email let password=creds.password console.log(this.$axios) return Vue.axios .post('/auth/signin', { email, password }) .then(r => { //console.log(r) //localStorage.setItem("token", "JWT"); commit('LOGIN_SUCCESS') return r }) .catch(e => { //console.log(e.response) Notify.create("Error: " + e.response.status) //localStorage.removeItem("token") commit('LOGOUT') return e }) } export const doLogout = (state) => { localStorage.removeItem("token") commit(LOGOUT) }
-
pass this to dispatch works, but looks terrible… any elegant solution?
-
You could also use
this._vm.$axios
… -
Thanks @benoitranque for this tid bit: http://forum.quasar-framework.org/topic/1898/services-and-axios-plugin
In order to use axios without passing in ‘this’ in the vuex store actions, you can do this:
import Vue from 'vue' export const AUTH_REQUEST = ({ commit, dispatch }, creds) => { return new Promise((resolve, reject) => { Vue.prototype.$axios({ .... }) } })
-
-
@steve said in Use Plugin inside Vuex module action:
Thanks @benoitranque for this tid bit: http://forum.quasar-framework.org/topic/1898/services-and-axios-plugin
In order to use axios without passing in ‘this’ in the vuex store actions, you can do this:
import Vue from 'vue' export const AUTH_REQUEST = ({ commit, dispatch }, creds) => { return new Promise((resolve, reject) => { Vue.prototype.$axios({ .... }) } })
I was scratching my head when I was writing some common library code to access this.$axios from my static plain javascript libs
this tip saved me having to pass in this or this.$axios … thanks!
-
Here’s my solution! Set axios.js as a plugin as usual but expose the instance, this way:
import axios from 'axios' const baseURL = 'https://dev.api.insylo.io/v2' const BEARER = localStorageAuth === null ? '' : 'bearer' + JSON.parse(localStorageAuth).token export const axiosHTTP = axios.create({ Authorization: BEARER, baseURL }) export default ({ Vue }) => { Vue.prototype.$axios = axiosHTTP }
Then from your Vuex module :
import { axiosHTTP } from '../plugins/axios' export function Login (context, payload) { return axiosHTTP({ method: 'post', url: '/login/', data: payload }) }
-
@benoitranque said in Use Plugin inside Vuex module action:
You could also use
this._vm.$axios
…this is a perfect solution because it is not only
$axios
. Sometimes you need to access notifications, loading bar, … This approach gives it all. Deep thanks! -
@Lou-Rectoret said in Use Plugin inside Vuex module action:
instead of this:
const BEARER = localStorageAuth === null ? ‘’ : ‘bearer’ + JSON.parse(localStorageAuth).token
it should be that:
const BEARER = localStorageAuth === null ? '' : 'bearer ' + JSON.parse(localStorageAuth).token