0
votes

Im creating a simple spa todo app with vue + vuex.

My problem is that each module will have the same 5 default method for manipulating the state. If i decide to change the default state management behavior then i have to go to every module and update them. The five actions that all modules should have when written out in the module work, but as soon as i import the exact same object and assign it to the actions property on the module the action cant be found. and i get this error [vuex] unknown action type: namespacedTodos/getCollection

  // This is in a component
  
  mounted: function () {
    this.$store.dispatch('namespacedTodos/getCollection')
  },

  // import baseActions from '../base-actions'
  import baseGetters from '../base-getters'
  import baseMutations from '../base-mutations'
  import axios from 'axios/index'
  import mainStore from '../index'
  // import _ from 'lodash'

  const namespacedTodos = {
    namespaced: true,
    state: {
      collection: [],
      defaultInstance: {},
      collectionLoaded: false,
      url: 'api/todos',
      namespace: 'namespacedTodos'
    },
    mutations: baseMutations,

    getters: baseGetters,

    actions: {
      getCollection: function ({state, commit}) {
        if (state.collectionLoaded) {
          return Promise.resolve({data: state.collection})
        }

        return axios.get(`${mainStore.state.baseUrl}/${state.url}`)
          .then((response) => {
            commit(`setCollection`, response.data.data)

            return response
          })
          .catch((response) => {
            console.log('Error Response: ', response)

            throw response
          })
      }
    },
    strict: process.env.NODE_ENV !== 'production'
  }

  export default namespacedTodos

The above Code Works But the following Dose Not

import baseActions from '../base-actions'
import baseGetters from '../base-getters'
import baseMutations from '../base-mutations'

const namespacedTodos = {
  namespaced: true,
  state: {
    collection: [],
    defaultInstance: {},
    collectionLoaded: false,
    url: 'api/todos',
    namespace: 'namespacedTodos'
  },
  mutations: baseMutations,

  getters: baseGetters,

  actions: baseActions,
  strict: process.env.NODE_ENV !== 'production'
}

export default namespacedTodos

import axios from 'axios'
import _ from 'lodash'
import mainStore from './index'

export default {
  getCollection: function ({state, commit}) {
    if (state.collectionLoaded) {
      return Promise.resolve({data: state.collection})
    }

    console.log('this: ', this)
    console.log('Namespace: ', state.namespace)

    return axios.get(`${mainStore.state.baseUrl}/${state.url}`)
      .then((response) => {
        commit(`setCollection`, response.data.data)

        return response
      })
      .catch((response) => {
        console.log('Error Response: ', response)

        throw response
      })
  },
}
1
I figured out how to get it to work. Simply need to use Object.assign(baseActions, {}) and assign that to the base actions. This works with the debug tools and will also namespace your base Mutations for you when used for default mutations. Works Great for minimizing duplicated code.Shawn Pivonka

1 Answers

1
votes

import baseActions from '../base-actions'
import baseGetters from '../base-getters'
import baseMutations from '../base-mutations'

const todos = {
  namespaced: true,
  state: {
    collection: [],
    defaultInstance: {},
    collectionLoaded: false,
    url: 'api/todos'
  },
  
  // The mutations get namespaced!!
  mutations: Object.assign(baseMutations, {}),

  // The getters get namespaced!!
  getters: Object.assign(baseGetters, {}),

  // The actions get namespaced!!
  actions: Object.assign(baseActions, {
    // any methods defined here will also be available
    // You can over write existing methods when nessicary
  }),
  strict: process.env.NODE_ENV !== 'production'
}

export default todos