The elements within the array are being refreshed accurately, however, a separate component is being removed

I have developed a component that has the ability to contain multiple Value components. Users can add as many values as they want, with the first value being mandatory and non-removable. When adding two new Value components, I provide input fields for name and description. An input event is emitted so that the parent component can store all values from the different components. Clicking on the remove button next to a value triggers a method in the parent component to remove it from the list of values. While the correct value gets removed from the updated list, the issue arises when it removes the last component instead of the intended one. The data in the list seems accurate but the created components do not reflect this properly, even retaining old values. I am having trouble pinpointing the mistake in my code.

ParentComponent

<div v-for="(component, index) in components" v-bind:key="index">
    <Value
        class="value"
        :valueIndex="index"
        v-model="components[index]"
        :id="'value_' + index"
        :isFirst="index === 0"
     ></Value>
</div>

export default {
    name: "Values",
    components: {
        Value
    },
    data() {
        return {
            components: [{
                name: "",
                description: ""
            }],
            componentsCount: 1
        }
    },
    methods: {
        addValue() {
            this.components.push({
                name: "",
                description: ""
            });
        },
        removeValue(valueIndex) {
            console.log(valueIndex);
            console.log(this.components[valueIndex]);
            this.components.splice(valueIndex, 1);
        }
    }

ValueComponent

<b-col md="4" sm="12">
     <input
         type="text"
         class="value-input"
         v-model="buffer.name"
         :name="'description_' + (this.valueIndex + 1)"
         :placeholder="'Description ' + (this.valueIndex + 1)"
         @input="$emit('input', buffer)"
     >
</b-col>
<b-col v-if="isFirst" md="8" sm="12">
    <input
        type="text"
        class="value-input"
        v-model="buffer.description"
        :name="'description_' + (this.valueIndex + 1)"
        :placeholder="'Description ' + (this.valueIndex + 1)"
        @input="$emit('input', buffer)"
    >
</b-col>
<b-col v-else md="8" sm="10">
    <b-row>
        <b-col sm="10">
             <input
                  type="text"
                  class="value-input"
                  v-model="buffer.description"
                  :name="'description_' + (this.valueIndex + 1)"
                  :placeholder="'Description ' + (this.valueIndex + 1)"
                  @input="$emit('input', buffer)"
             >
         </b-col>
         <b-col sm="2">
             <button class="garbage-button" @click="removeValue()">
                  <img src="../../assets/bin.svg">
             </button>
         </b-col>
     </b-row>
</b-col>

     export default {
            name: "Value",
            props: {
                valueIndex: {
                    type: Number,
                    required: true
                },
                isFirst: {
                    type: Boolean,
                    required: true
                }
            },
            data() {
                return {
                    buffer: Object.assign({}, this.value)
                }
            },
            methods: {
                removeValue() {
                    this.$parent.removeValue(this.valueIndex);
                }
            }
        }
    }

If more code is needed or if there are any clarifications required, please let me know.

Answer №1

In the past, I encountered a similar issue where positions were being mistakenly deleted due to confusion.

The solution that ultimately resolved this for me involved implementing unique identifiers. By utilizing uuidv4, I was able to successfully correct the problem. This tool generates distinctive keys that can be applied to your items for binding purposes.

Answer №2

This pertains to the concept of in-place-patch feature in Vue, where using the index as a key may not be effective. It is advised to use another unique key like an id, as mentioned in other responses. The issue arises when the value assigned to buffer in the child component is only done once, resulting in the value not being updated when changes occur. To resolve this, you can utilize the watch property and adjust the buffer accordingly when changes are made within your v-for loop:

props: {
  // ...
  value: {
    type: Object,
    default: () => {
      return {};
    }
  }
},
data() {
  return {
    buffer: Object.assign({}, this.value)
  };
},
watch: {
  value(val) {
    this.buffer = val;
  }
}

DEMO

It's important to note that although the correct item is being deleted, the value is not updating due to the way Vue interacts with v-for loops.

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

When utilizing the .populate() method in Mongoose, how can you retrieve and append ObjectIds with extra attributes to an array (which is returned by .populate()) collected from the

When using the .populate() method in Mongoose, how can I retrieve and add ObjectIds with additional properties to an array (returned by .populate()) if their corresponding document in the collection no longer exists? This question pertains to MongoDB and ...

Trouble updating outside controller data while using AngularJS directive inside ng-repeat loop

I am currently working with a isolate scope directive that is being used inside an ng-repeat loop. The loop iterates over an array from the controller of the template provided below: <!DOCTYPE html> <html> <head> <link rel="sty ...

Extracting Query Parameters from a Successful Ajax Call in Javascript

How can I extract data from the success response? Take a look at my code snippet: $.ajax({ async: 'true', url: 'https://exampleapi.com/product', type: 'GET', data: {page: idQuery}, success:(response => { v ...

Exploring the Versatility of Axios

Today, I implemented an AJAX request using Axios in JavaScript to submit form data. While the requests are being sent successfully, it seems that the backend is not able to receive the username and password information from the frontend. What could be ca ...

Numerous documents within a JavaScript application

As a newcomer to JavaScript, I've been experimenting with the language to enhance my understanding. One aspect that puzzles me is how developers organize large JavaScript programs. In languages like Java, breaking down code into smaller files is commo ...

Ways to calculate the total number of keys within a JSON object at a certain level

I need to process a JSON file by extracting values from keys located at a specific depth. The initial value I want to access is situated here: json.children[0].children[0].children[0] Is there a method to navigate through the JSON object at a particular ...

JSONP error: "Syntax error - token not expected"

While attempting to perform a JSONP AJAX request, an error was thrown: Uncaught SyntaxError: Unexpected token I'm puzzled about what is wrong in my code. Can someone assist? $.ajax({ url: 'http://api.server32.trustklik.com/apiv1/website/ ...

What causes a never-ending loading cycle on a website when a 404 error occurs?

My Express.js/Node.js website is hosted on Heroku. I am facing an issue where the server does not properly send a 404 error when a file cannot be found. Instead, the page keeps loading endlessly. How can I make the server stop loading when it encounters a ...

Issues with Disabling the Browser's Back Button with jquery

I have been attempting to prevent the back button from functioning in a specific Browser, Microsoft Bing. Interestingly, my code works only if I click somewhere in the window first. If I don't click anywhere and try to go back directly, it still allow ...

React's constructor being invoked twice

As a newcomer to react, I am in the process of developing a simple web application but encountering an issue. It seems like my Constructor is being called twice when I load a class component. Can anyone provide some assistance? Home.js import React from ...

typescript: the modules with relational paths could not be located

As part of a migration process, I am currently converting code from JavaScript to TypeScript. In one of my files 'abc.ts', I need to import the 'xyz.css' file, which is located in the same directory. However, when I try to import it usi ...

Is it possible to send both props and a function within a single onClick event in React?

After spending hours searching for the right solution, I have yet to find it. Let me explain my situation clearly. I have an Image Carousel feature on my website that should open when a user clicks on an image. I have 5 images on the website, and when a us ...

What is the best method for directing a search URL with an embedded query string?

Currently, I am developing an express application that has two different GET URLs. The first URL retrieves all resources from the database but is protected by authentication and requires admin access. The second URL fetches resources based on a search para ...

Displaying server errors in an Angular componentIn this tutorial, we

As I work on creating a registration page, my focus has been on posting data to the server. I have successfully implemented client-side and server-side validation mechanisms. Managing client-side errors is straightforward using code such as *ngIf="(emailAd ...

Using AngularJS to transfer data from a datepicker to an ng-model

I am currently trying to figure out how to pass the date from a datetimepicker into the model. Unfortunately, I am facing some challenges with this process. I wish I could provide a demo of the issue on a fiddle, but I am unsure of how to do so due to the ...

The appearance of the pop-up mask is displayed at lightning speed

Check out the demo here Here is the HTML code: <div class="x"> </div> <input class="clickMe" type="button" value="ClickMe"></input> This is the JS code: $(".clickMe").click( function() { ...

A guide on using jQuery to iterate through 3 separate div elements

Seeking assistance with creating a dynamic loop for multiple divs (3 or more) using jQuery. The desired outcome is to have the main image div on the homepage rotate with other divs, changing both the background image and links within each div. I initially ...

Creating a dynamic HTML table using Vue 3

My table is not showing the data I'm fetching from my API. Even though I can see the data in my console.log, it's not populating the table. Could there be an issue with how I'm calling the data to display in the table? <template> < ...

JavaScript/jQuery boolean data type

In my current coding project, I am dealing with a scenario where the user has the option to download either a specific "Slice" of a pie chart or the entire chart. When a user clicks on a slice, it sends a variable named source to indicate which slice was ...

Executing functions in Vue TypeScript during initialization, creation, or mounting stages

Just a few hours ago, I kicked off my Vue TypeScript project. I've successfully configured eslint and tslint rules to format the code as desired, which has left me quite pleased. Now, I'm curious about how to utilize the created/mounted lifecycl ...