v-for not working even when variable has object array assigned to it

Viewed 49
                    <tbody>
                        <tr v-for="invoice in invoices">
                            <td>Holder</td>
                            <td>{{invoice.firstname}} {{invoice.lastname}}</td>
                            <td>{{invoice.telephone}}</td>
                            <td>{{invoice.email}}</td>
                            <td>{{invoice.payment_adress_1}} {{payment_country}} {{payment_postcode}}</td>
                            <td>{{invoice.shipping_address}} {{shipping_country}} {{shipping_postcode}}</td>
                            <td>{{invoice.comment}}</td>
                            <td>Holder</td>
                            <td>{{invoice.payment_method}}</td>
                            <td>Holder</td>
                            <td>Holder</td>
                            <td>Holder</td>
                        </tr>
                    </tbody>
    <script>
        const app = Vue.createApp({
            data() {
                return {
                    invoices: []
                }
            },
            methods: {
                OnLoad() {
                    axios.post('invoiceConfig.php', {
                        request: 3
                    })
                    .then(function(response){
                        console.log(response.data)
                        this.invoices = response.data
                        console.log(this.invoices)
                    })
                    .catch(function(error){
                        console.log(error);
                    });
                }
            },
            beforeMount(){
                this.OnLoad()
            }
        })
        const vm = app.mount('#app');

enter image description here

enter image description here

invoiceConfig.php is used to extract data from a database, for some reason, when console logging the response, an object array is seen, but when trying to v-for to add rows to table corresponding to the amount of objects in the list, it simply doesnt work. Anyone has any idea why?

3 Answers

Try the same using computed

 <tbody>
   <tr v-for="(invoice, index) in getInvoices" :key="index"> <!-- Change added in this line -->
                            <td>Holder</td>
                            <td>{{invoice.firstname}} {{invoice.lastname}}</td>
                            <td>{{invoice.telephone}}</td>
                            <td>{{invoice.email}}</td>
                            <td>{{invoice.payment_adress_1}} {{payment_country}} {{payment_postcode}}</td>
                            <td>{{invoice.shipping_address}} {{shipping_country}} {{shipping_postcode}}</td>
                            <td>{{invoice.comment}}</td>
                            <td>Holder</td>
                            <td>{{invoice.payment_method}}</td>
                            <td>Holder</td>
                            <td>Holder</td>
                            <td>Holder</td>
  </tr>
</tbody>
<script>
        const app = Vue.createApp({
            data() {
                return {
                    invoices: []
                }
            },
            // change added below
            computed: {
             getInvoices() {
               return this.invoices.length ? this.invoices : [];
             }
            },
            methods: {
                OnLoad() {
                    axios.post('invoiceConfig.php', {
                        request: 3
                    })
                    .then(function(response){
                        console.log(response.data)
                        this.invoices = response.data
                        console.log(this.invoices)
                    })
                    .catch(function(error){
                        console.log(error);
                    });
                }
            },
            created(){ // change added
                this.OnLoad();
            }
        })
        const vm = app.mount('#app');

Okay I don't know how this works but, changing .then(function(response)... to .then(response)=>... in the OnLoad() method fixed it. I guess this is not recognized in an inner function? I followed this guide to solve it: Axios can't set data, first answer!

Ideally your code should work, I just created a below code snippet by adding some time out to see if beforeMount() is binding the data in the DOM after some interval or not but it is working.

Are you getting any error in console ? Can you please try with some dummy/mock response to debug the actual root cause.

Demo :

new Vue({
  el: '#app',
  data: {
    invoices: []
  },
  beforeMount() {
    this.OnLoad();
  },
  methods: {
    OnLoad() {
      setTimeout(() => {
        this.invoices = [{
          id: 1,
          name: 'Invoice 1'
        }, {
          id: 2,
          name: 'Invoice 2'
        }, {
          id: 3,
          name: 'Invoice 3'
        }]
      }, 2000);
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <table>
  <thead>
    <th>ID</th>
    <th>Name</th>
  </thead>
  <tbody>
    <tr v-for="invoice in invoices" :key="invoice.id">
      <td>{{ invoice.id }}</td>
      <td>{{ invoice.name }}</td>
    </tr>
  </tbody>
  </table>
</div>

Related