Vuejs and datatables: table empty when using v-for to fill data

Clash Royale CLAN TAG#URR8PPPVuejs and datatables: table empty when using v-for to fill data
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:
<div class="row">
<div class="col-sm-12">
<div class="box box-color box-bordered">
<div class="box-title">
<h3>
<i class="fa fa-table"></i>
</h3>
</div>
<div class="box-content nopadding">
<table id="suppliersTable" class="table table-hover table-nomargin table-bordered dataTable">
<thead>
<tr>
<th>Supplier #</th>
<th>Company</th>
<th class='hidden-1024'>Email</th>
<th class='hidden-480'>Phone</th>
<th class='hidden-480'>Fax</th>
<th class='hidden-480'>Mobile</th>
<th class='hidden-480'>City</th>
<th class='hidden-480'>Street</th>
<th class='hidden-480'>Postal Code</th>
<th class='hidden-480'>CR</th>
<th class='hidden-480'>Website</th>
<th class='hidden-480'>Notes</th>
</tr>
</thead>
<tbody>
<tr class="template" v-for="supplier in suppliers">
<td class='verticalAlignMiddle'>{{ supplier.Supplier_ID }}</td>
<td class='verticalAlignMiddle'>{{ supplier.Company }}</td>
<td class='verticalAlignMiddle hidden-1024'>{{ supplier.Email }}</td>
<td class='verticalAlignMiddle hidden-480'>{{ supplier.Phone }}</td>
<td class='verticalAlignMiddle hidden-480'>{{ supplier.Fax }}</td>
<td class='verticalAlignMiddle hidden-480'>{{ supplier.Mobile }}</td>
<td class='verticalAlignMiddle hidden-480'>{{ supplier.City_ID }}</td>
<td class='verticalAlignMiddle hidden-480'>{{ supplier.Street }}</td>
<td class='verticalAlignMiddle hidden-480'>{{ supplier.Postal_Code }}</td>
<td class='verticalAlignMiddle hidden-480'>{{ supplier.CR }}</td>
<td class='verticalAlignMiddle hidden-480'>{{ supplier.Website }}</td>
<td class='verticalAlignMiddle hidden-480'>{{ supplier.Notes }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
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();
},
}
@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.
– Mahmoud Dafer
Jul 23 at 0:13
okay added please help :)
– Mahmoud Dafer
Jul 23 at 0:22
Is your suppliers object empty or not? And what do you mean by "it doesn't recognize it"? Please show the errors from VueDevTools.
– gil
Jul 23 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
– Mahmoud Dafer
Jul 23 at 0:48
2 Answers
2
Once initialized, DataTables does not automatically reparse the DOM. Here's a relevant FAQ:
DataTables
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.
row.add()
row().data()
row().remove()
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().
table.destroy()
$nextTick()
DataTables
suppliers
DataTables
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
first, thanks a lot @tony19! but it gives an error: TypeError: suppliers.map is not a function.. i tried to use Array.from() then map, the error is gone but the table is not getting filled
– Mahmoud Dafer
Jul 23 at 10:10
What is the data type and value of
suppliers in your case?– tony19
Jul 23 at 14:36
suppliers
suppliers is an object (idk why it's not an array of objects).. suppliers: {"1" : {" ":" "}, "2": {" ":" "}....}
– Mahmoud Dafer
Jul 23 at 15:32
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).– tony19
Jul 23 at 15:57
suppliers
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>
its the same, you only changed the fetching way but the returned data is the same but thanks anyway :D
– Mahmoud Dafer
Jul 23 at 9:39
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
You'll need to show the component's script including the ajax call and initialization of data.
– Alexander Staroselsky
Jul 22 at 23:59