Home > database >  VueJS, loading attribute dynamic with json object
VueJS, loading attribute dynamic with json object

Time:02-02

I have a problem on my last Vue JS page. I think I am totally wrong.

Let me explain, I have a button which make an API GET call to the backend and I got an array as a response from the API.

When I received this array, I push data in this.templates.

I have a v-for on this array :

<v-flex
      
      xs12
      md4
      v-for="item of templates"
      :key="item._id"
    >

with inside :

<v-card elevation="10" :loading="loadingTemplates[item._id]">

When I received the response, v-card are correctly displayed with loading true. After this, I have a second POST request for each element, and when I received the response, I set to false the value :

console.log(`Response for ${element._id} and ${element.loading}`);
this.loadingTemplates[element._id] = false;

Log is OK, i have ID and true value. I set false, but loading is still displayed....

Why ?

Maybe I need to use json object for templates, but i don't know how. TO resume : GET Request ==> Get Array with x jobs POST Request for x jobs ==> With v-simple-table displayed.

CodePudding user response:

As @stellr42 mentioned in his comment, Vue 2 has some limitations on reactivity when it comes to arrays. You can have a look into this official documentation.

Vue cannot detect the following changes to an array :

  • When you directly set an item with the index, e.g. this.loadingTemplates[element._id] = false
  • When you modify the length of the array, e.g. this.loadingTemplates.length = newLength

Demo as per the above statements :

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    loadingTemplates: [true, true, false, true]
  },
  mounted() {
    this.loadingTemplates[1] = false; // Not updating
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <ul>
    <li v-for="item_id in [0, 1, 2, 3]">{{ loadingTemplates[item_id] }}</li>
  </ul>
</div>

Hence, To update and make it reactive - You also have to trigger state updates in the reactivity system.

Working Demo :

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    loadingTemplates: [true, true, false, true]
  },
  mounted() {
    this.$set(this.loadingTemplates, 1, false);
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <ul>
    <li v-for="item_id in [0, 1, 2, 3]">{{ loadingTemplates[item_id] }}</li>
  </ul>
</div>

  • Related