delete input based on index of a click event from parent vue

I’m working with BootstrapVue.

I want to splice my inputs in my child.vue after clicking on a button in my parent.vue.

But every time I delete something in my parent.vue – which I can promise that it’s working – only the last Input element in my child.vue will be deleted.

If you want to try it do following (you can copy paste the code and run it):

  1. Add 3 Inputs
  2. Open every Input and write a number into it like Input 1 -> 1111, Input 2 -> 2222 and Input 3 -> 3333 (you can also add more Input Informations, but it’s not really relevant in here)
  3. Delete for example the second Input, normally it should now be like Input 1 -> 1111, Input 2 -> 3333 but it’s always Input 1 -> 1111 and Input 2 is still 2222, because it’s always deleting the last input Informations..

How can I solve this problem, that the correct input Informations will be deleted as well?

Thank You very much!

update:

The mistake is that the index in my parent.vue is changing after deleting something, but in my child.vue it did not delete the correct index and also did not recreate all other indexes

code in my parent.vue:

<template>
  <div>
    <div class="inputArea mt-2" v-for="(id, indexParent) in inputs" :key="indexParent">
      <div class="col-md-12">
        <b-button-group>
          <b-button class="col-md-6" v-b-toggle="'newInput' + indexParent" variant="danger">Input</b-button>
          <b-button class="col-md-6" @click="deleteThis(indexParent)" variant="danger">Delete</b-button>
        </b-button-group>
      </div>

      <child :key="indexParent" :indexParent="indexParent" ref="ChildComponent" />
    </div>

    <div class="mt-3 mb-3 ml-3 mr-3">
      <b-button @click="addThis()" variant="success">Add Input</b-button>
    </div>
  </div>
</template>


<script>

import child from './child.vue'

export default {
  name: "parent",

  components: {
    child,
  },

  data() {
    return {
      inputs: [{}],
    };
  },

  methods: {
    deleteThis(indexParent) {
      this.inputs.splice(indexParent, 1);
      this.$refs.ChildComponent[indexParent].deleteThisFromParent(indexParent);
    },

    addThis() {
      this.inputs.push({});
    },
  },
};
</script>

my child.vue:

<template>
  <b-collapse visible :id="'newInput' + indexParent" class="mt-2">
    <div v-for="(id, indexChild) in inputs" :key="indexChild">
    <table class="table table-striped mt-2">
      <tbody>
        <h5 class="ml-1">Input Informations</h5>
        <tr>
          <div class="mt-2">Input</div>
          <b-form-input></b-form-input>
        </tr>
      </tbody>
    </table>
    </div>

    <b-button @click="addInputInfo()">Add Input Informations</b-button>
  </b-collapse>
</template>



<script>
export default {
  name: "child",

  methods: {
    deleteThisFromParent(indexParent) {
      console.log(this.inputs); //Here I get the correct input which I want to delete
      console.log(indexParent); //correct index of parent.vue
      this.inputs.splice(); //here it deletes the last Input everytime.. 
    },

    addInputInfo() {
      this.inputs.push({});
    },
  },

  props: ["indexParent"],

  data() {
    return {
      inputs: [{}],
    };
  },
};
</script>

Answer

Simple answer.

Setting an unique id in my array was the solution!

Changings in my template: Set :key to id.id (which I will create in my script) and pass after clicking my deleteButton my unique ID to methods.

<div class="inputArea mt-2" v-for="(id, indexParent) in inputs" :key="id.id">
  ....
  <b-button class="col-md-6" @click="deleteThis(id.id)" variant="danger">Delete</b-button>
  ....

</div>

Changings in script: Set id: null, and give the first automatically generated input -> id = 0. After that go to methods and reference splice to the index which I’m getting after search over the complete array with map. In addInput I set the unique Id each time my button will be clicked.

data() {
    return {
      id: null, 
      inputs: [{
        id: 0,
      }],
    };
  },

  methods: {
    deleteThis(id) {
      this.inputs.splice(id.id, 1);
    },

    addThis() {
      this.inputs.push({
        id: this.id += 1
      });
    },
  },

Last step is to change the passed values to my child.vue:

<child :key="id.id" :indexParent="id.id"/>

After that everything where indexParent is still included could be changed to id.id

This is working out for me well!

Source: stackoverflow
The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .