title: Array change detection for an array of complex objects in Vue JS 2
body: <p><strong>Update</strong></p>
  <p>Vue JS 3 will properly handle this: <a href="https://blog.cloudboost.io/reactivity-in-vue-js-2-vs-vue-js-3-dcdd0728dcdf" rel="nofollow noreferrer">https://blog.cloudboost.io/reactivity-in-vue-js-2-vs-vue-js-3-dcdd0728dcdf</a></p>
  <p><strong>Problem:</strong></p>
  <p>I have a vue component that looks like this:</p>
  <p>sub-comp.vue</p>
  <pre><code>&lt;template&gt;
      &lt;div&gt;
          &lt;input type=&quot;text&quot; class=&quot;form-control&quot; v-model=&quot;textA&quot;&gt;
          &lt;input type=&quot;text&quot; class=&quot;form-control&quot; v-model=&quot;textB&quot;&gt;
          &lt;input type=&quot;text&quot; class=&quot;form-control&quot; v-model=&quot;textC&quot;&gt;
      &lt;/div&gt;
  &lt;/template&gt;
  &lt;script&gt;
      export default {
          props: {
              textA: {
                  type: Number,
                  required: false
              },
              textB: {
                  type: Number,
                  required: false
              },
              textC: {
                  type: Number,
                  required: false
              }
          }
      }
  &lt;/script&gt;
  </code></pre>
  <p>I have a parent component that looks like this:</p>
  <p>layout-comp.vue</p>
  <pre><code>&lt;template&gt;
      &lt;div&gt;
          &lt;button @click=&quot;addItem&quot;&gt;Add&lt;/button&gt;
          &lt;ul&gt;
              &lt;li v-for=&quot;listItem in listItems&quot;
                  :key=&quot;listItem.id&quot;&gt;
                  &lt;sub-comp 
                        :textA=&quot;listItem.item.textA&quot;
                        :textB=&quot;listItem.item.textB&quot;
                        :textC=&quot;listItem.item.textC&quot;
                  /&gt;
              &lt;/li&gt;
          &lt;/ul&gt;
      &lt;/div&gt;
  &lt;/template&gt;
  import subComp from '../sub-comp.vue'
  export default {
      components: {
          subComp
      },
      data() {
          return {
              listItems: []
          }
      },
      methods: {
          addItem: function () {
              var item = {
                           textA: 5,
                           textB: 100,
                           textC: 200
                         }
              if (!item) {
                  return
              }
              this.length += 1;
              this.listItems.push({
                  id: length++,
                  item: item
              });
          }
      } 
  &lt;/script&gt;
  </code></pre>
  <p>The thing is, anything I do to edit the textboxes, the array doesn't get changed, even though the reactive data shows that it changed. For example, it will always be as</p>
  <pre><code> { 
       textA: 5,
       textB: 100, 
       textC: 200 
   }
  </code></pre>
  <p>Even if I changed textB: 333, the listItems array still shows textB: 100. This is because of this:</p>
  <p><a href="https://v2.vuejs.org/v2/guide/list.html#Caveats" rel="nofollow noreferrer">https://v2.vuejs.org/v2/guide/list.html#Caveats</a></p>
  <blockquote>
  <p>Due to limitations in JavaScript, Vue cannot detect the following changes to an array</p>
  </blockquote>
  <p><strong>Question:</strong></p>
  <p>I'm wondering how do I update the array? I also want the change to occur when leaving the textbox, using the @blur event. I'd like to see what ways this can be done.</p>
  <p>I read these materials:</p>
  <p><a href="https://codingexplained.com/coding/front-end/vue-js/array-change-detection" rel="nofollow noreferrer">https://codingexplained.com/coding/front-end/vue-js/array-change-detection</a>
  <a href="https://v2.vuejs.org/v2/guide/list.html" rel="nofollow noreferrer">https://v2.vuejs.org/v2/guide/list.html</a></p>
  <p>But it seems my example is a bit more complex, as it has indexes associated, and the arrays have complex objects.</p>
  <hr />
  <p><strong>Update 4/12/2018</strong></p>
  <p>Found out that in my addItem() that I had:</p>
  <pre><code>item = this.conditionItems[this.conditionItems.length - 1].item);
  </code></pre>
  <p>to</p>
  <pre><code>item = JSON.parse(JSON.stringify(this.conditionItems[this.conditionItems.length - 1].item));
  </code></pre>
  <p>I was thinking the sync modifier in the answer below was causing problems because it duplicated all items. But that's not the case. I was copying a vue object (including the observable properties), which caused it to happen. The JSON parse and JSON stringify methods only copies the properties as a normal object, without the observable properties. This was discussed here:</p>
  <p><a href="https://github.com/vuejs/Discussion/issues/292" rel="nofollow noreferrer">https://github.com/vuejs/Discussion/issues/292</a></p>