skip to Main Content

Short description of the project: An invoice card is to be displayed that contains information about an invoice. The user can assign payments to the invoice and also remove them. The payments are stored as an object in an array.

<tr class="invoice-form-wrapper invoice" v-if="item.payments.length > 0" >
     <td colspan=6>
         <template
             v-for="payment in item.payments"
             :key="payment.index"
         >
             <InvoiceForm
                  :invoiceItem="payment"
                  :calcRemainingFromInput="calcRemainingFromInput"
                  :removeForm="removeForm"
              />
         </template>
     </td>
</tr>

When removing a payment, the method removeForm is called which removes the object with the function filter():

removeForm(item) {
   for(let i = 0; i < this.invoice.invoice.length; i++) {
       let payments = this.invoice.invoice[i].payments;
       if(payments.includes(item)) {
            this.invoice.invoice[i].payments = payments.filter(obj => obj !== item);
       }
   }
}

The problem is that whenever the method is called, the last element disappears in the browser and not the element you want to remove. If you click on the element again, nothing happens. But when I display the array with console.log, the correct element is removed.

Does anyone have any ideas? I think Vue is not re-rendering the array correctly.

2

Answers


  1. I guess your :key="payment.index" is wrong (index is undefined). Vue cannot map the updated data to the DOM.

    You could use

     <template
                 v-for="(payment, index) in item.payments"
                 :key="index"
             >
    
    Login or Signup to reply.
  2. When you modify an array directly, Vue might not detect the change and update the view accordingly. To ensure Vue reactivity works correctly, you should use Vue’s set or splice methods when modifying arrays nested within objects. Try this updated removeForm method

    removeForm(item) {
    for (let i = 0; i < this.invoice.invoice.length; i++) {
        let payments = this.invoice.invoice[i].payments;
        if (payments.includes(item)) {
            const index = payments.indexOf(item);
            if (index !== -1) {
                this.$set(this.invoice.invoice[i].payments, index, null);
                this.invoice.invoice[i].payments = this.invoice.invoice[i].payments.filter(obj => obj !== null);
            }
        }
    }
    }
    

    In this updated method, we first set the element to null using Vue.set at the index we want to remove, and then we use the filter method to remove the null elements from the array. By doing this, Vue will be able to detect the change and update the view correctly.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search