Using destructuring assignment in a Vuex mutation is not possible

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
        }
    }
}

Answer №1

To tackle this problem, one approach is to utilize the delete operator while also ensuring that you are not altering the original object by creating a deep clone of it.

removeAvailableHelp (state, name) { 
  const res = {...state.availableHelp}; 
  delete res[name]; 
  state.availableHelp = res; 
} 

Answer №2

Your implementation of destructuring is slightly different from the correct way it should be. The accurate approach would look like this:

removeItem (state, id) {
  const { id: unused, ...rest } = state.items
  state.items = rest
}

Since you are aliasing your id to unused, there is no need for brackets around the id.

To illustrate further, here is an example I experimented with in devtools:

const state = {
  id: 2308147,
  description: "hello world",
  beaconId: "1248ad890"
}

const { id: unused, ...rest} = state // unused: 2308147, rest: {description: 'hello world', beaconId: "1248ad890"}
state.items = rest
console.log(state) // { beaconId: "1248ad890", description: "hello world", id: 2308147, items: Object { description: "hello world", beaconId: "1248ad890" }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Facing issues with Laravel errors preventing the implementation of CSS on my localhost

These are the tailwindcss errors I am encountering: npm WARN @tailwindcss/[email protected] requires a peer of tailwindcss@^1.0 but none is installed. You must install peer dependencies yourself. npm WARN @tailwindcss/[email protected] requi ...

Having trouble retrieving a remote JSON link from a local HTML file in Google Chrome

Having trouble fetching a JSON from the following link: [https://www.nseindia.com/api/equity-stockIndices?index=NIFTY%2050]. When accessed through a browser, the JSON is displayed on screen as expected. However, attempting to fetch this link from JavaScrip ...

How can I retrieve the chosen value from an AJAX combobox using JavaScript in an ASP.NET C# application?

How can I retrieve the selected value from an AJAX combobox item using JavaScript in ASP.NET C#? Below is the code snippet: <asp:ComboBox ID="dropdown_dest" runat="server" Width="90%" onfocusout="blurFunction()" AutoCompleteMode="SuggestAppend" CssCla ...

Troubleshooting a 400 Bad Request Error in jQuery Ajax for WordPress Widgets

I am attempting to send information to admin-ajax.php in order to save it as a $_POST variable for handling on the cart page. However, my .ajax function keeps failing. var sendJsonA = {'value':'Data coming from JSON'} var ajaxurl = $ ...

Is it secure to store information that impacts component rendering within a JWT payload?

I am currently developing a MERN app where users have various roles, and different components are rendered based on their role in React. In my application, I store a JWT containing the user's ID and role in a cookie, which is then decoded in a global ...

Issue with Chrome not triggering onMouseEnter event when an element blocking the cursor disappears in React

Important Note: This issue seems to be specific to Chrome Currently, React does not trigger the onMouseEnter event when a blocking element disappears. This behavior is different from standard JavaScript events and even delegated events. Below is a simpli ...

Top approach for triggering and re-triggering AJAX using php

I'm in the process of deciphering instructions from my developer. Our approach may not be entirely correct, so I want to ensure that we are on the right track. This is our objective: On a webpage, there exists a button. When this button is clicked, I ...

Problem with React Router: Uncaught Error - Invariant Violation: The element type is not valid, a string is expected for built-in components

I am encountering an issue with react-router and unable to render my app due to this error. Here is a screenshot of the error I have searched extensively for a solution but have not been able to find anything useful. Any help would be greatly appreciated ...

Deploying: only publish newly generated files and exclude any previously generated files that are no longer present

After checking out this discussion regarding setting Build Action for an entire folder in Visual Studio, I found a solution that worked for me. My webpack configuration generates hashed files in a Build folder which are then published. However, I encounter ...

Ways to pass information from a parent component to a child component in Vue.js

I am currently embarking on my Vue.js journey by creating an app for educational purposes. Here is what I aim to achieve: In my parent component, there are multiple buttons with distinct IDs. The child component will await these IDs from the parent and ...

Issue with Confirming Password in Laravel Validation

I am currently incorporating Vue.js into my Laravel project and I am facing an issue with validating a confirmation password. Despite entering matching passwords, I continue to receive an error stating that they do not match. <div class="control-grou ...

Utilizing WebView and Javascript for Push Notifications

Is it feasible to utilize javascript on an external page within a WebView application to trigger push notifications? (For instance, if I have a function located at example.com/news, would it be possible to send a push notification from there?) Appreciate ...

I'm feeling a bit lost when it comes to assigning and defining variables in AngularJS,

Currently embarking on developing my own game leveraging the latest JavaScript, AngularJS, and Node.js technologies. My approach in handling users and players is inspired by the code found here: https://github.com/amirrajan/nodejs-against-humani ...

Making a XMLHttpRequest/ajax request to set the Content-Type header

In my attempts, I have tested the following methods individually: Please note: The variable "url" contains an HTTPS URL and "jsonString" contains a valid JSON string. var request = new XMLHttpRequest(); try{ request.open("POST", url); request.set ...

What is the best way to bring in modules using JSX?

Hello, I am a newcomer to React and have recently integrated it into my project by following the instructions provided on this resource: https://reactjs.org/docs/add-react-to-a-website.html Executing npm init -y (in case of failure, see the fix below) Ru ...

Is there a way to incorporate an MTN Momo or Orange Money payment system into your application if you are not a registered business entity?

Implementing an MTN Momo and Orange Money payment system through their respective APIs is crucial. In addition, I am seeking a dependable and effective method to seamlessly integrate these diverse APIs. During my attempt to incorporate the API via their ...

Numerous ajax requests

I am utilizing a for-loop to make multiple ajax requests: for(var o = 1; o <= 2; o++) { $.ajax({ type: 'GET', url: 'lib/terrain.php', ...

Creating a collection of arrays that are named based on the properties of an object

After calling an ajax service, I received a collection of objects where Object (A) properties are Group, order, salary. For example, the objects could be [Employee, 1, 1500],[Management, 2, 2000], [Employee, 3, salary]. My task is to create an array for e ...

Mastering various mathematical operations in Vue.js

I am attempting to calculate the percentage of a value and then add it back to the original value using Vue.js. Here is an example: 5 / 100 * 900 + 900 = 945.00 (standard calculation) 5 / 100 * 900 + 900 = 90045 (Vue.js calculation) This is the code I ha ...

Vue3 - i18n - It looks like you are currently using the esm-bundler version of the vue-i18n package

Currently tackling a new project using Vue3 and integrating version 9 of vue-i18n (). Although I've set up the project, I'm facing difficulty changing the language. The translations are working as expected, as evidenced by the {{ $t('message ...