Lukas Ignatavičius
Lukas Ignatavičius

Reputation: 3615

Vuex store is undefined

I am using vuex, axios for my app and I want to use getter in axios initiation to pass basic auth. This is my axios init (http-common.js):

import axios from 'axios'
import store from '@/store'

export default axios.create({
  baseURL: 'http://localhost:8081/',
  auth: store.getters['authentification']
})

When I am debugging my app I find store undefined. Can someone explain what am I doing wrong? Store itself works fine in all the components.

My store has several modules and those modules. store index.js:

import m1 from './modules/m1'
import m2 from './modules/m2'
import authentification from './modules/authentification'

Vue.use(Vuex)
export default new Vuex.Store({
  modules: {
    authentification,
    m1,
    m2
  }
})

And modules uses axios init function for calling REST api i.e. :

import HTTP from '@/common/http-common'  
.....
const actions = {
  action ({commit}) {
        HTTP.get('item')
            .then(response => {
              commit('MUTATION', {response})
            })
  }
}
.....
export default {
  state,
  getters,
  actions,
  mutations
}

I think this creates loop and calls http-common before store is being initialized.

Edit: adding authentification module as requested:

import * as types from '../mutation-types'

const state = {
  isLoggedIn: !!localStorage.getItem('auth'),
  auth: JSON.parse(localStorage.getItem('auth'))
}
const getters = {
  isLoggedIn: state => {
    return state.isLoggedIn
  },
  authentification: state => {
    return state.auth
  }
}
const mutations = {
  [types.LOGIN] (state) {
    state.pending = true
  },
  [types.LOGIN_SUCCESS] (state) {
    state.isLoggedIn = true
    state.pending = false
  },
  [types.LOGOUT] (state) {
    state.isLoggedIn = false
  }
}
const actions = {
  login ({
      state,
      commit,
      rootState
    }, creds) {
    console.log('login...', creds)
    commit(types.LOGIN) // show spinner
    return new Promise(resolve => {
      setTimeout(() => {
        localStorage.setItem('auth', JSON.stringify(creds))
        commit(types.LOGIN_SUCCESS)
        resolve()
      }, 1000)
    })
  },
  logout ({ commit }) {
    localStorage.removeItem('auth')
    commit(types.LOGOUT)
  }
}

export default {
  state,
  getters,
  actions,
  mutations
}

Upvotes: 0

Views: 2297

Answers (2)

Aaron F
Aaron F

Reputation: 11

This is actually a better solution shown to me by Thorsten Lünborg (LinusBorg) of the Vue core team:

https://codesandbox.io/s/vn8llq9437

In the file that you define your Axios instance in and set configuration, etc., you have also got a Vuex plugin that watches your store and sets/deletes your Authorization header based on the presence of whatever auth token in your store.

Upvotes: 1

Lukas Ignatavičius
Lukas Ignatavičius

Reputation: 3615

I have found a sollution. I had to assign auth before the call and not during inicialization of axios object:

var axiosInstance = axios.create({
  baseURL: 'http://localhost:8081/'
})

axiosInstance.interceptors.request.use(
  config => {
    config.auth = store.getters['authentification']
    return config
  }, error => Promise.reject(error))

export default axiosInstance

Upvotes: 0

Related Questions