UPDATE: Upon further investigation, I have discovered that Vuex may allow direct state mutation in mutations, unlike Redux where state is treated as immutable. Most of my research indicates that this is an acceptable practice, which allows me to bypass the need for destructuring assignment in the first place.
Issue: An error is thrown by Vuex when collecting modules if I use destructuring assignment within a module's mutation.
Attempted Solutions: The error is resolved by commenting out the destructuring assignment.
Observations: The mutation does not seem to get called, and no console.log
messages are recorded.
Versions: [email protected], [email protected], node v10.17.0
removeItem (state, id) {
const { [id]: unused, ...rest } = state.items
state.items = rest
}
vuex.common.js:272 Uncaught TypeError: Cannot read property 'getters' of undefined
at vuex.common.js:272
at Array.forEach (<anonymous>)
at assertRawModule (vuex.common.js:271)
...
To pinpoint what seems to be causing the issue, the following syntax generates an error in Vuex:
removeItem (state, id) {
const { [id]: unused, ...rest } = state.items
}
However, the error does not occur with the following syntax:
removeItem (state, id) {
const { [id]: unused } = state.items
}
It was discovered that we are transpiling with browserify, resulting in the following code:
removeReadyHelp: function removeReadyHelp(state, name) {
var _state$items = state.items,
unused = _state$items[name],
rest = _objectWithoutProperties(_state$items, [name]);
}
...
function _objectWithoutProperties(obj, keys) {
var target = {};
for (var i in obj) {
if (keys.indexOf(i) >= 0) continue;
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
target[i] = obj[i];
}
return target;
}
The provided code represents the entire Vuex module. The problematic mutation is removeAvailableHelp
(the mutation above removeItem
has been made generic.)
import helpApi from '../../api/api-viewed-help.js'
/**
* Information about available help required to trigger it from the help list.
* @typedef {object} Help
* @property {string} Help.name Uid name of help.
* @property {HelpTrigger} Help.trigger
*/
/**
* Callback function that triggers the available help in the help list.
* @callback HelpTrigger
* @returns {void}
*/
export const module = {
namespaced: true,
state: {
viewedHelpNames: [],
availableHelp: {},
hydrated: false
},
actions: {
/**
* Populate Vuex state from database.
* @param {*} vuex
* @param {string} usercode Usercode to fetch viewed help by.s
*/
async hydrate ({ commit }, usercode) {
const viewedHelpNames = await helpApi.getAllViewedHelpNames(usercode)
commit('_setViewedHelpNames', viewedHelpNames)
commit('_hydrated')
}
},
mutations: {
/**
* Replace all viewed help names with provided array.
* @param {*} state
* @param {string[]} viewedHelpNames
*/
_setViewedHelpNames (state, viewedHelpNames) {
state.viewedHelpNames = viewedHelpNames
},
_hydrated (state) {
state.hydrated = true
},
/**
* @param {*} state Vuex
* @param {Help} help
*/
addAvailableHelp (state, help) {
state.availableHelp[help.name] = help
},
removeAvailableHelp (state, name) {
const { [name]: unused, ...res } = state.availableHelp
state.availableHelp = res
}
}
}