Search code examples
authenticationvuejs2axioscsrfnuxt.js

Unable to find Vuex module action in Nuxt


I'm working on a Nuxt site with a custom Django back end, and I'm trying to set up a mechanism where when the app loads, I call a /token/ URL to get a CSRF token, and then store it in Vuex state to be used in a custom header that is set for every subsequent request.

First, here is my store/index.js:

import Vue from 'vue'
import Vuex from 'vuex'
import auth from '@/store/auth'

const debug = process.env.NODE_ENV !== 'production'

Vue.use(Vuex)

const store = () => {
  return new Vuex.Store({
    namespaced: true,
    modules: {
      auth
    }
  })
}
export default store

and store/auth.js:

import { SET_TOKEN } from './types'

const state = () => ({
  token: ''
})

const getters = {
  token: state => state.token
}

const actions = {
  setToken({ commit, dispatch }, token) {
    commit(SET_TOKEN)
  }
}

const mutations = {
  [SET_TOKEN](state, token) {
    state.token = token
  }
}

export default {
  state,
  getters,
  mutations,
  actions
}

One thing I can't figure it is where to put my mounted function so it's always triggered on page reload. In a regular Vue app, it's App.vue, but I haven't been able to find what that same thing is in Nuxt. For now, I just use index.vue. I'm also using the @axios Nuxt module to communicate with the back end.

<script>
import Cookie from 'js-cookie'

export default {
  mounted() {
    this.getCSRFToken()
  },
  methods: {
    async getCSRFToken() {
      // Call the URL that sets the csrftoken cookie
      const tokenRequest = await this.$axios.$get('/token/')
      // Get the cookie value
      const token = Cookie.get('csrftoken')
      // Save it to the store./
      this.$store.dispatch('auth/setToken', token)
    }
  }
}
</script>

I can call the URL just fine and get the value from the cookie, but when I go to dispatch my action, I get an error that says [vuex] unknown action type: auth/setToken.

I followed the example here to set up my state. My questions are these:

  1. What is a common starting point in Nuxt that I can use to always load this on page refresh/initial load?

  2. What do I need to change in my setup so that my action is found?


Solution

  • The issue is that your auth module is not namespaced.

    Change the default export to

    export default {
      namespaced: true,
      state,
      getters,
      mutations,
      actions
    }
    

    You should probably remove namespaced: true from your root store.


    I recommend you change to using Nuxt's Module Mode as the Classic Mode you're using will be removed in Nuxt 3. For example

    // store/auth.js
    import { SET_TOKEN } from './types'
    
    export const state = () => ({
      token: ''
    })
    
    export const actions = {
      setToken({ commit, dispatch }, token) {
        commit(SET_TOKEN)
      }
    }
    
    export const mutations = {
      [SET_TOKEN](state, token) {
        state.token = token
      }
    }