Home > Net >  Vue is not iterating through my object after I fetch properties from an api?
Vue is not iterating through my object after I fetch properties from an api?

Time:01-18

I have an object which I want to iterate and display as a table with v-for but it seems that object v-for is not detecting that the object has changed.

<tr v-for="(value, key) in translations">
<td>@{{ value.ar }}</td>
<td>@{{ value.en }}</td>
<td>@{{ key }}</td>
</tr>

Vue code

import {createApp} from "vue";
import axios from 'axios';

const translationApp = createApp({
    data() {
        return {
            translations:{}
        }
    },
    created() {
        axios.get("/api/translation").then(response => {
            if (response.status === 200) {
                this.translations = response.data;
            }
        });
    }
});


translationApp.mount("#translations-app");

and it is clear that object get populated:

NOTE:

the @{{}} Syntax is because I am using Laravel Blade.

enter image description here

CodePudding user response:

After setting the translations to a new value like this

this.translations = newValue

Vue has no idea that it's properties had changed, because you've overriden it's proxied object.

Try doing it like this

this.$set(this, 'translations', newValue)

This way you're telling Vue to proxy this new object (make it 'reactive') so it knows when it's properties change.

You can do a console.log on that object and see for yourself that it has new properties defined by Vue that weren't set by you explicitly.

Another option would be to define all possible keys at the property initialization, and override these key's values instead of a whole object.

return {
  translations: {
    key1: null,
    key2: null
    ...
...
this.translations.key1 = newKey1Value

Read more about reactivity on Vue docs

CodePudding user response:

Your code should work fine as I did not see any issue in the implementation you have. I am assuming you are getting an array of objects from an API response which you are assigning back into the translations data variable.

Live Demo :

const app = Vue.createApp({
  data() {
    return {
      translations:{}
    }
  },
  created() {
    // Just for a demo purpose I am using setTimeout and mock data.
    setTimeout(() => {
      this.translations = [{
        ar: 'a',
        en: 'b'
      }, {
        ar: 'c',
        en: 'd'
      }]
    }, 500)
  }
})

app.mount('#app')
<script src="https://unpkg.com/[email protected]/dist/vue.global.js"></script>
<div id="app">
  <table>
    <tr v-for="(value, index) in translations">
      <td>{{ value.ar }}</td>
      <td>{{ value.en }}</td>
      <td>{{ index }}</td>
    </tr>
  </table>
</div>

You can have a quick look into the above demo and try to find the root cause of the issue you are facing.

  • Related