Ways to remove items from Vuex store by utilizing a dynamic path as payload for a mutation

I am looking to implement a mutation in Vuex that dynamically updates the state by specifying a path to the object from which I want to remove an element, along with the key of the element.

  1. Triggering the action
deleteOption(path, key) 
{ this.$store.dispatch('deleteOptionAction', {path, key}) }
  1. Executing the mutation
deleteOptionAction ({ commit }, payload) { commit('deleteOption', payload) }
  1. The mutation is passed with the payload where the path is 'state.xmlValues.Offers[0].data.Pars' and the key is 0
deleteOption (state, payload) { 
  let stt = eval('state.' + payload.path)
  Vue.delete(stt, payload.key)
  // delete stt[payload.key] - works the same as Vue.delete
  state.xmlValues.Offers[0].data.Pars = Object.assign({}, Object.values(stt))
   }

I attempted using the state[payload.path] syntax, but it did not work. The path contains the string 'state.xmlValues.Offers[0].data.Pars', so I used let stt = eval('state.' + payload.path) to make it function. However, deleting an element from the state posed a challenge: when Vue.delete(stt, payload.key) is used, it only removes the element key locally stored in stt variable, rather than in the state itself.

Subsequently, I updated the state objects with stt (from which the required element was already deleted), hardcoding the path - something I aim to avoid:

state.xmlValues.Offers[0].data.Pars = Object.assign({}, Object.values(stt))

How can I send a path to the store, then utilize it to erase an object in the state without explicitly coding the path?

Similarly, for my other mutation addOption, I utilized a dynamic path to the state object - and achieved success by evaluating the dynamic path within stt

addOption (state, payload) {
      let stt = eval('state.' + payload.path)
      Vue.set(stt, payload.key, payload.newEl)
   }

Answer №1

As a fundamental rule, it is strongly advised to avoid using the eval(..) function. The execution of arbitrary code is enabled through this function, and no attempt is made to sanitize the input value!

A more sensible approach would involve manually parsing the path. While you could create your own solution, lodash conveniently provides the toPath function for this purpose. It generates an array containing each segment of the desired path.

Once we understand how to access the target key for deletion, we can develop a piece of code that verifies the existence of each segment and whether they are objects or arrays. Nonetheless, leveraging lodash tools like _.get and _.isObjectLike can streamline our task:

import { toPath, get, isObjectLike } from 'lodash-es';

function deletePath(source, pathStr) {
    const path = toPath(pathStr);

    const selector = path.slice(0, -1);
    const key = path[path.length - 1];

    let deletableSource = source;

    if (selector.length && isObjectLike(source)) {
      deletableSource = get(source, selector);
    }

    if (isObjectLike(deletableSource)) {
        // Deletion operation can be performed here!
        this.$delete(deletableSource, key);
    }
}

With this implementation in place, the function can be assigned to the Vue prototype or exported as a helper function elsewhere. As an exercise, I suggest reworking your current addOption method.

https://codesandbox.io/s/q9p0j903q?fontsize=14

Answer №2

Shoutout to @Sumurai8 for enlightening me on the fact that passing a parameter doesn't have to be in the form of a string, but can actually be a reference to the store like this. Therefore, there is no longer a need to pass the string containing the path to the object in the state.

<button @click="deleteOption($store.state.xmlValues.Offers[mainData.curOfferKey].data.Pars)">delete</button>

In addition, the lodash functions get and toPath proved to be invaluable!

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

How can you display a personalized modal or error message using React context while incorporating dynamic content?

Can you please help me figure out how to display a custom modal or error message using react context with dynamic content? I attempted it like this: https://codesandbox.io/s/sleepy-wozniak-3be3j import React, { useState } from "react"; import ErrorConte ...

Trigger a dialogue box when a button is clicked to show dynamically inserted list elements

My goal is to have a collection of list items, each with its own button that triggers a unique dialog box displaying specific text. Below is the HTML code: <ul id="filter-list" class="scrollable-menu text-center"> @foreach (var filter in ...

Utilizing Nuxt.js for Enhanced Authentication with <nuxt-link />

I have a secure route in my Nuxt application that should only be accessible to authenticated users: /dashboard/secret. On the /dashboard page, there is a link like this: <nuxt-link to="/dashboard/secret">Link to the "secret" page</nuxt- ...

What is the reason this switch statement functions only with one case?

Why is the switch statement not functioning properly? It seems to correctly identify the values and match them with the appropriate case, but it only works when there is a single case remaining. If there are multiple cases to choose from, nothing happens. ...

Having trouble getting the JQuery Tipsy tooltip to display correctly with D3.js circles?

Below is the d3.js code that I have used: var circles = vis.selectAll("circle").data(data) circles .enter() .append("svg:circle") .attr("stroke", "black") .attr("cx", function (d) { return xRange(d.year); }) ...

Assign a value to the cookie based on the input from the form

I recently asked a similar question, but it seems like I missed providing some context, which is why I couldn't get it to work. My goal is to set a cookie value of a form entry when clicking on it (using the carhartl jquery plugin), but nothing happen ...

Recurly.js version 3 with additional features

I'm currently exploring the functionality of addons in Recurly.js v3. For my form, I've linked a recurly.Pricing instance and added a checkbox for an optional addon: HTML <label for="plan-mobile" class="checkbox"> <input type="check ...

JavaScript, XML, and PHP all support the use of HTML entities within their code

Having some trouble as a newbie again))) Can you please help me out, guys? I'm having an XML file with the following data: <Page> <Content>&lt;p&gt;Article content&lt;/p&gt;&#13; &#13; &lt;h1 style="font-style ...

Updating a URL once AngularJS has finished processing it

Currently, I am utilizing Primo, an AngularJS app developed by Ex Libris. This application functions as a library catalog, enabling users to explore both physical and digital collections within the library. Despite not having direct access to the original ...

Determine the percentage of payments, similar to Upwork, by leveraging the power

Currently, I am working on developing a percentage calculation similar to what is seen on the Upwork website. The calculation appears to be accurate when derived from the base amount at a rate of 10%. For instance, if we take a base amount of 89.00, the ...

Using dynamic jquery to target specific elements. How can we apply jquery to selected elements only?

Hello everyone! I have been working on a simple hover color change effect using jQuery, but I noticed that I am repeating the code for different buttons and service icons. Is there a way to achieve the same result so that when a button is hovered, the co ...

Using Three.JS to navigate a 3D cube by utilizing accelerometer data on both the x and y axes

After referencing my previous question I'm currently working on a 3D model that responds to input from accelerometer and gyroscope sensors. The 3D model is created using three.js, and the input data for rotation and translation is in JSON format. How ...

Using PHP to ascertain the requested dataType or responseType from the client

My ajax request is fairly simple: $.post('server.php',data, function (json) {console.log(json)},'json'); I have configured jQuery to expect json data based on the dataType setting. Question: Is the dataType parameter equivalent to re ...

I am looking to showcase images beside individuals' names or photos on my website in a vertical arrangement, similar to how it is done on Facebook

Looking for suggestions on how to display images uploaded by users on my webpage in a way similar to Facebook, with the user's photo displayed beside each image. Any recommendations or website links would be greatly appreciated. Thanks, Santosh Sahu ...

The Firebase JQuery .on method is incrementally updating individual values in an array instead of updating them all simultaneously

I am trying to update the values of the orders placed by users on the Corporate's page without a refresh. I have implemented the jQuery .on method for this purpose. However, the values are being returned one by one from the array created for the order ...

AngularJS does not function upon reloading the browser

I am currently working on a new project that involves the following components: Node.js (v0.10.37) Express micro framework Jade templating engine Angular.js (latest) Material design library (material.angularjs.org) Jquery One issue that I am facing is r ...

Form an object using elements of a string array

Trying to convert a string array into an object. The string array is as follows : let BaseArray = ['origin/develop', 'origin/master', 'toto/branch', 'tata/hello', 'tata/world']; I want the resulting obje ...

Ways to safeguard your API endpoint

Just starting out with Node.js/Express, I'm looking to have my front end retrieve data from an endpoint ('/1') without displaying the JSON data to users when they access that specific endpoint. Any guidance on how to accomplish this would be ...

Error message: Unexpected character found at the beginning of JSON data - REST API using node.js and Express

Recently, I have embarked on the journey of learning REST API with node and express. My main goal is to achieve file read and write operations using APIs. However, a frustrating error arises when attempting to hit the API through Postman. Strangely enough, ...

unable to retrieve the value from the scope

I'm trying to implement the following code in HTML: <div ng-if="item.shareText"> <textarea></textarea> <div> <select ng-model="shareOptions"> <option value="PUBLIC" selected>public</option> ...