In Vue.js, the splice method consistently removes the final item from an array

I've been stuck on this seemingly simple problem for hours.

I developed an app that allows users to add or remove files for upload.

However, whenever I click the delete button, it always removes the last item. I tried adding :key="key", but it didn't make a difference.

What could be wrong with my code? Here is the link to the CodePen: https://codepen.io/shanyulin/pen/RwaWaZy?editors=1010

HTML

<div id="app">
  <div class="form-group clearfix" v-for="(event, key) in events" v-bind:key="key">
  <input name="attachment[]" accept="image/png, image/jpeg, application/pdf" type="file" class="form-control form-control-lg">
  <button @click="deleteEvent(key)" class="btn btn-danger">x</button>
</div>
<button @click="addEvent" class="btn btn-dark">+</button>
</div>

Js

const app = new Vue({
    el: '#app',
    data() {
        return {
            events: [{}],
           }
    },
    methods: {
        addEvent: function() {
            let quantity = this.events.length;
            if (quantity < 6) {
                this.events.push({
                    index: ''
                });
            } else {
                return false;
            }
        },
        deleteEvent: function(key) {
            let quantity = this.events.length;
            if (quantity == 1) {
                alert("Please upload at least one file.");
            }
            if (quantity > 1) {
                const confirmed = confirm("Do you really want to delete?");
                if (confirmed) {
                    this.events.splice(key, 1);
                }
            }
        }
    },
});

Answer №1

It is important to note that the array index is not a reliable method for assigning keys in Vue.js. For example, if you have an array with three elements, the keys would be 0,1,2. However, if you were to remove the second element, the keys would then become 0,1, not 0,2.

To ensure stability and uniqueness, it is recommended to provide a unique key for each element in the array.

const app = new Vue({
    el: '#app',
    data() {
        return {
            events: [{}],
            uniqueKey: 0,
           }
    },
    methods: {
        addEvent: function() {
            let quantity = this.events.length;
            if (quantity < 6) {
                this.events.push({
                    index: '',
                    key: this.uniqueKey++
                });
            } else {
                return false;
            }
        },
        deleteEvent: function(key) {
            let quantity = this.events.length;
            if (quantity == 1) {
                alert("Please upload at least one file.");
            }
            if (quantity > 1) {
                const confirmed = confirm("Do you really want to delete?");
                if (confirmed) {
                    this.events.splice(key, 1);
                }
            }
        }
    },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div class="form-group clearfix" v-for="(event, key) in events" v-bind:key="event.key">
  <input name="attachment[]" accept="image/png, image/jpeg, application/pdf" type="file" class="form-control form-control-lg">
  <button @click="deleteEvent(key)" class="btn btn-danger">x</button>
</div>
<button @click="addEvent" class="btn btn-dark">+</button>
</div>

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

Guide on accessing an array within a JSON object?

I have the following JSON object: [ { "comments": [ { "created_at": "2011-02-09T14:42:42-08:00", "thumb": "xxxxxxx", "level" ...

Meteor, the challenges of rendering reactive arrays during updates

I am currently working with a nested template and using a ReactiveDict to store the data. The data includes variables such as color, type, as well as an array of children nodes. However, I have encountered an issue during refresh: although the array displ ...

Having trouble with Axios on Android after compiling with Phonegap?

I'm facing an issue with my Phonegap .apk file after building it on their platform. The problem lies with axios not functioning properly, although it works fine in my Desktop Phonegap App. I'm unsure of the root cause behind this, could it be rel ...

The Laravel and Vue fetch operation is yielding no results on the front end, despite the data being successfully

Within my Vue template, I am using the following code snippet... <template> <div id="container"> {{show_municipality_in_words(12)}} </div> </template> In my JavaScript file... export default { data() { }, met ...

What is the best method to delete an attribute from an element using Angular?

When working with Angular, how can I remove an attribute or its value? For example, say I have an ng-click event that I only want to fire once. One approach could be to create a 'self-destruct' in the ng-click event like this: elementClicked = f ...

What is the best way to iterate through files within a directory and its nested subdirectories using electron?

I am currently working on developing a desktop application that involves scanning through a directory, including all subdirectories, to locate files containing specific characters in their filenames. Is it feasible to accomplish this task using Electron? ...

Utilize the <select> tag to dynamically update the state based on user input. Filter through a list of categories to selectively display blog posts from

I have created a dynamic dropdown list of categories by saving their names in an array and now I want to update my list of blog posts based on the selected category from the dropdown. The array containing categories is as follows: const tags = ['Sust ...

Jest does not allow mocking a module and validating function invocations at the same time

After setting up a new project using create-app-component, which includes build scripts (babel, webpack, jest), I proceeded to write a React component that requires another javascript file containing a function. The contents of my search.js file are as fo ...

Using JavaScript, sift through various elements in a large array and extract only specific

I have retrieved an array containing 2400 objects from our server, totaling about 7MB in size, and I need to extract specific values from it. Currently, I am using a combination of the filter and slice methods: const keyword = 'whatever word'; ...

What is the significance of including the *dispatch* variable in the *dependency array* for the useEffect function?

While reviewing the source code of a ReactJS project, I noticed that the dispatch variable is included in the dependency array of the useEffect hook. Typically, I'm familiar with including useState() variables in this context, so I am curious about th ...

When dealing with back-end data in JavaScript, converting long types can result in a

When parsing data of the Object type in C#, utilizing JavaScript on the front end to parse the data can result in loss of precision. <!DOCTYPE html> <html> <head> <title>Example using BigNumber.js</title> <script s ...

How to access the onchange text in a react-select search component

I'm currently working on implementing search select functionality in my webpage using the react-select-search npm package. This is my main component: import React, { Component } from "react"; import Task from "./task"; // Rest of ...

Setting up Stylelint in a Vue 3 app with VSCode to automatically lint on save

I am looking to perform linting on my scss files and scss scope within .vue components. Here is what my configuration looks like in stylelint.config: module.exports = { extends: [ 'stylelint-config-standard', 'stylelint-config-rece ...

When passed as a parameter to a Firebase dynamic link, the access token for Firebase storage is automatically removed

I have uploaded an audio file to firebase storage and I need to include its URL along with an access token as a parameter in the firebase dynamic link. I want my file.component.ts to be publicly shareable on platforms like WhatsApp and Facebook, and below ...

What could be preventing the spinning cube from rendering in three.js?

While there are no errors showing up, the result is just a black screen. Due to the small size of the HTML and CSS code snippets, I suspect the issue lies within the JavaScript. // Creating a three.js scene: a 3D environment for objects const scene = new ...

ReactJS form submissions failing to detect empty input values

My goal is to use react to console.log the input value. Below is the code I've created: import React from 'react'; import ReactDOM from 'react-dom'; class App extends React.Component{ constructor() { super(); this.proce ...

Preparing to dive into the world of HTML5

As a desktop application developer, I am considering diving into the world of HTML5. However, with limited published books and information available for beginners due to its unreleased status, I am debating whether to start with HTML4 and current web devel ...

Combining text in Nativescript with the help of Label

I am trying to combine a string in a Label. The desired result is : USD 3000, where 3000 is the price number retrieved from the database. I have tried using the following code: <Label row="2" col="1" text="USD {{ price }}" /> However, it does not w ...

The setTimeout function interrupts the event loop

Recently, I came across conflicting information regarding the usage of setTimeout to create nonblocking/asynchronous functions. One article suggested that using setTimeout is essential for this purpose, while another claimed that it actually blocks the eve ...

Easy Navigation Slider with CSS3 and jQuery

I'm currently working on implementing a push menu on my website. The objective is to have the menu slide out from the left and overlap the current page content. I've written the code below but it doesn't seem to be functioning as expected. C ...