Detecting changes in arrays in Vue.js 2

Below is a simplified version of the code :

<template>

    /* ---------------------------------------------- 
     *  Displaying a list of templates, @click to select the template
    /* ----------------------------------------------
    <ul>
        <li 
            v-for="form in forms.forms" 
            @click="selectTemplate(form)" 
            :key="form.id" 
            :class="{selected: templateSelected == form}">
            <h4>{{ form.name }}</h4>
            <p>{{ form.description }}</p>
        </li>
    </ul>

    /* ----------------------------------------------------
     *  Displaying the "Editable fields" of the selected template
    /* ----------------------------------------------------

    <div class="form-group" v-for="(editableField, index) in editableFields" :key="editableField.id">                                       
        <input 
                type="text" 
                class="appfield appfield-block data-to-document" 
                :id="'item_'+index" 
                :name="editableField.tag" 
                v-model="editableField.value">
    </div>                    
</template>
            
<script> 
    export default {                        
        data: function () {
            return {
                editableFields: [],
            }
        },
        methods: {
            selectTemplate: function (form) {

                /* ------------------
                *  The issue lies here
                */ ------------------

                for (let i = 0; i < form.editable_fields.length; i++) {                                         
                    this.editableFields.push(form.editable_fields[i]);              
                }
            }
        }
    }
</script>

The challenge I am facing is that Vuejs does not update the display when the array EditableFields is modified. To address this issue, I have referred to the documentation, which suggests using $set or Array instance methods like splice and push.

The current implementation (using push) works, but the array never gets cleared, causing the "editable fields" to accumulate, an undesirable behavior.

To clear the array before populating it with new data, I have attempted multiple approaches without success:

this.editableFields.splice(0, this.editableFields.length);

for (let i = 0; i < form.editable_fields.length; i++) {
    this.editableFields.push(form.editable_fields[i]);                   
}

==> Does not update the display

for (let i = 0; i < form.editable_fields.length; i++) {                 
    this.$set(this.editableFields, i, form.editable_fields[i]);
}

==> Does not update the display

this.editableFields = form.editable_fields;

==> Does not update the display

One solution I haven't tried yet is setting a completely new array with fresh data. However, implementing this seems challenging as I want users to be able to click (and change template selection) multiple times.

I have been struggling with this problem for several hours now and would greatly appreciate any assistance. Thank you in advance :) !

Answer №1

I have no issues utilizing splice and push in my code. The reactivity will function as expected, just like the way it was explained in the link you shared.

Take a look at this snippet of my code:

new Vue({
  el: '#app',
  data: function() {
    return {
      forms: {
        forms: [{
            id: 'form1',
            editable_fields: [{
                id: 'form1_field1',
                value: 'form1_field1_value'
              },
              {
                id: 'form1_field2',
                value: 'form1_field2_value'
              }
            ]
          },
          {
            id: 'form2',
            editable_fields: [{
                id: 'form2_field1',
                value: 'form2_field1_value'
              },
              {
                id: 'form2_field2',
                value: 'form2_field2_value'
              }
            ]
          }
        ]
      },
      editableFields: []
    }
  },
  methods: {
    selectTemplate(form) {
      this.editableFields.splice(0, this.editableFields.length);
      for (let i = 0; i < form.editable_fields.length; i++) {
        this.editableFields.push(form.editable_fields[i]);
      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app">
    <ul>
        <li v-for="form in forms.forms" 
            @click="selectTemplate(form)" 
            :key="form.id">
            <h4>{{ form.id }}</h4>
        </li>
    </ul>

    <div class="form-group"
        v-for="(editableField, index) in editableFields"
        :key="editableField.id">
            {{ editableField.id }}:
        <input type="text" v-model="editableField.value">
    </div>
</div>

Answer №2

Issue resolved! It turns out that a separate section of the code was actually causing the problem.

Just a heads up for next time, this is the correct solution:

this.editableFields.splice(0, this.editableFields.length);

for (let i = 0; i < form.editable_fields.length; i++) {
    this.editableFields.push(form.editable_fields[i]);                   
}

Stick to using Array instance methods when working with Vuejs.

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

Locate the nearest neighbor for each given point to find the closest point

We have a method that takes an array of points as input and aims to find, for each point in the array, the closest point to it (excluding itself). Currently, this process involves a brute force approach of comparing every point with every other point. The ...

Incorporating the outcome of an asynchronous function into my 'return' statement while iterating through an array

Issue I am Facing I encountered a problem while trying to execute a database function while simultaneously mapping an array. To illustrate this problem in a more concise manner, I have developed a sample code snippet. In my implementation, I am utilizing ...

Bizarre results observed while printing in the C programming language

Recently transitioned from Java to C and feeling a bit lost. I attempted to create a multiplication table by printing an array, but encountered some issues. Everything seems to be working fine, except after the first iteration of printing the array, zeroes ...

What is causing the slow performance of this JavaScript array retrieval?

I am working with a large array called frames_to_boxes, consisting of 5000 elements. Each element is an array of Objects belonging to the Box class: class Box { constructor(x, y, width, height, frame, object_class, id) { this.x = x; this.y = y; ...

Exclude the node_modules directory when searching for files using a global file pattern

I'm facing some challenges setting up a karma configuration file because I am having difficulty creating a glob that correctly matches my files. Within my lerna repository, there may be node_modules folders inside the packages, and it's importan ...

Using AngularJS to dynamically load content into Owl Carousel 2

I'm having trouble loading the owl carousel in angularjs dynamic content. Here is the modified html code I am using: <div id="Galeria" owlcarousel class="youplay-carousel gallery-popup"> <a class="angled-img" href="http://www.youtube. ...

Creating a 2D array of pointers in ANSI C through dynamic allocation

I have come across a scenario where I need to create an array of pointers (M rows, N cols), with each pointer pointing to a float vector of variable length (L). Can you guide me on how to dynamically establish this array? The challenge is that the values o ...

Trouble with selecting inputs within a Div Element

Could you please review the code below and help me understand why I am unable to retrieve the ID of the selected radio buttons using this.id? <div id="pay" class="btn-group" data-toggle="buttons"> <label class="btn btn-primary"> < ...

"Exploring the Magic of Jquery's Fadein() Animation

i have experience with writing code for a jQuery fadein effect. imagine I have an HTML element stored in a variable, like this: var sHtml="<div>Other content</<div><div id='frm'>hello</<div>"; modal.load(jQuery(sHt ...

The `this` value is null within an onClick function of a ReactJS component

The issue occurs with the onClick method of <span className="nav-toggle">. The specific error message is: cannot read property setState of null. It seems to be related to the scoping of this or due to the asynchronous nature of the setState method. ...

Fetching data using JSONRequest sample code

I am new to web development and this is my first attempt at using JSON. On the JSON website (http://www.json.org/JSONRequest.html), they recommend using JSONRequest.get for certain tasks. However, I keep running into an error stating "JSONRequest is not ...

Trigger a single occurrence of the function upon element creation and pass it to VueJS methods

Currently, I am working with BootstrapVue and would like to provide a brief overview of my code: I have a v-for loop with inputs that can be dynamically created using a b-button named "addElement". Additionally, I have the option to select an item from a ...

Unable to access attribute of instantiated class

I am relatively new to TypeScript and I recently encountered a problem that's stumping me. I'm working on setting up a REST API using Express. The setup involves a router that calls a controller, which in turn invokes a service method before ret ...

How can one locate all instances of a specific input value in a two-dimensional array's indices?

Writing a function in Python to find the x,y coordinates of recurring values in a 2D array has been my latest challenge. For instance, given the array and a value: array = [ [1 ,2 ,3] [2 ,3 ,1] [3 ,2, 1]] search = 1 The expected outp ...

Issue with rendering an object's property using EJS

Trying to include the author's username in reviews within an ejs template for my app. The following code snippet: <%= review.author %> is functioning correctly and displays: { _id: 5eff6793e7f26811e848ceb1, username: 'mike', __v: 0 ...

Replacing a function in TypeScript

Looking to alter the behavior of the alert function in TypeScript? You can achieve this by creating a new function that wraps around the original alert and modifies its behavior. alert = (function (origAlert) { return function (...messages: any[]) { ...

The Array Find() method keeps returning 'undefined' when trying to search for data based on URL parameters

Is there a way to display data from an array based on a specific condition? I have been attempting to do this by checking if the requested id matches any of the ids in the data array. Unfortunately, whenever I run the following code snippet, I always end u ...

Rendering the page using ReactDOM.render

Just started with ReactJS, I'm struggling to figure out why my page isn't displaying anything - <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> ...

Error: The VueComponent.onResize function encountered an uncaught TypeError because it cannot read the property 'offsetHeight' of an undefined variable

<div ref="controls" class="varie controls"> <div class="control" v-if="spin!='"> <span>Saved datee</span><span>{{ }}</span> </div> <button v-on:click="apply()">Aopply</button> </div& ...

Ways to Determine if the Content in the CKEditor has Been Altered

Is there a way to detect changes in the content of CKEditor? I want to trigger a JavaScript function every time the content is updated. ...