3

I'm trying to fill a datatable using vuejs v-for directive and ajax to get the data but the table is always showing "No data available in table" even though there are some data shown and also in the bottom says "Showing 0 to 0 of 0 entries". I guess this is because vuejs is reactive and the table can't recognize the changes maybe? I've been searching and trying for a while but with no solution found..

thanks a lot! :)

here's the template:

<table id="suppliersTable" class="table table-hover table-nomargin table-bordered dataTable">
    <thead>
        <tr>
            <th>...</th>
            ...
        </tr>
    </thead>
    <tbody>                            
        <tr v-for="supplier in suppliers">
            <td>{{ supplier.Supplier_ID }}</td>
            <td>...</td>
            ...
        </tr>
    </tbody>
</table>

and the vue and ajax:

<script>
export default {
    data() {
        return {
            suppliers: [],
        }
    },
    methods: {
        fetchSuppliers() {
            this.$http.get('http://localhost/curemodules/public/suppliers/list')
            .then(response => {
                this.suppliers = JSON.parse(response.bodyText).data;
            });
        }
    },
    created() {
        this.fetchSuppliers();
    },
}

5
  • You'll need to show the component's script including the ajax call and initialization of data. Commented Jul 22, 2018 at 23:59
  • @AlexanderStaroselsky i simply have an empty suppliers array in vue data field that gets filled with $.ajax get method. this does the work and fills the table but it doesn't recognize it. Commented Jul 23, 2018 at 0:13
  • Is your suppliers object empty or not? And what do you mean by "it doesn't recognize it"? Please show the errors from VueDevTools. Commented Jul 23, 2018 at 0:43
  • @gil the suppliers gets filled and they are shown in the table, but what doesn't change is the count of entries in the table and it says "no data" (above the already shown data) meaning that you can't use the sort and search functions in the table Commented Jul 23, 2018 at 0:48
  • Where is the markup/logic for the total/count row? Are you using some sort of third party module or are you calculating total and sorting/filtering manually via something like computed/watched properties? If you are using a third party library/module/component you need to specify that in your question including the setup/configuration. Commented Jul 23, 2018 at 2:12

3 Answers 3

8

Once initialized, DataTables does not automatically reparse the DOM. Here's a relevant FAQ:

Q. I append a row to the table using DOM/jQuery, but it is removed on redraw.

A. The issue here is that DataTables doesn't know about your manipulation of the DOM structure - i.e. it doesn't know that you've added a new row, and when it does a redraw it will remove the unknown row. To add, edit or delete information from a DataTable you must use the DataTables API (specifically the row.add(), row().data() and row().remove() methods to add, edit and delete rows.

However, you can call table.destroy() to destroy the current instance before reinitializing it. The key is to delay the reinitialization until $nextTick() so that Vue can flush the DOM of the old DataTables. This is best done from a watcher on suppliers so that the DataTables reinitialization is done automatically when the variable is updated in fetchSuppliers().

mounted() {
  this.dt = $(this.$refs.suppliersTable).DataTable();
  this.fetchSuppliers();
},
watch: {
  suppliers(val) {
    this.dt.destroy();
    this.$nextTick(() => {
      this.dt = $(this.$refs.suppliersTable).DataTable()
    });
  }
},

demo

Sign up to request clarification or add additional context in comments.

4 Comments

What is the data type and value of suppliers in your case?
suppliers is an object (idk why it's not an array of objects).. suppliers: {"1" : {" ":" "}, "2": {" ":" "}....}
Hmm. You commented that the data was originally appearing in the table with the code you have in question, so I assume suppliers was originally an array of objects. If that's changed now, you'd have to update the processing in the front-end (or fix the backend to use the expected format).
@MahmoudDafer It turns there's out a simpler solution that doesn't require data manipulation (i.e., usage of map), allowing you to keep the HTML in the template as you had originally. Check out my updated answer.
5

I know this is a bit late answer but I just encountered this problem just today and my only solution for this issue is using setTimeout function.After fetching data using axios I set a bit of delay then init the data-table. With this work around v-for works fine.

See below for my code.

GetDepartmentList(){
           axios.get('department')
                .then((response) => {

                    this.departmentList = response.data;
                    // this.dataTable.rows.add(response.data).draw();
                    setTimeout(() => $('#department-data-table').DataTable(), 1000);

                })
                .catch((error) => {
                    if (error.response.status == 401) {
                        alert('User session has expired. Please login again.');
                        location.replace("/login");
                    }
                });
        },

Also you can use .rows.add() function if you want to draw row data in the table without using v-for of vue. Refer to this doc.

1 Comment

awesome! thanks for your answer. But I'm already done with that project and if you want you can use @tony19 's answer above, it works like a charm :D
-1

You can using Axios in Vuejs, you try see the following above:

<template>
    <div class="danhsach">
      <h2>{{title}}</h2>
        <table class="table">
            <thead>
              <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Password</th>
                <th>Age</th>
              </tr>
            </thead>
            <tbody>
                <tr v-for='data in datas'>
                  <td>{{data.id}}</td>
                  <td>{{data.name}}</td>
                  <td>{{data.password}}</td>
                  <td>{{data.age}}</td>
                </tr>
                 
            </tbody>
        </table>
    </div>
 </template>
 <script>
  export default{
      data(){
        return {
          title:"Tile Lists",
          datas:[]
        }
      },
      created:function(){
        this.danhsach_user();
      },
      methods:{
          danhsach_user(){
           this.axios.get('https://599f807effe73c0011b9fcc5.mockapi.io/api/user').then((response)=>{
             this.datas=response.data;
            });
          }
      }
  }
 
 
 </script>
 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.