I’m working on a data table with Alpine.js, but I’m not able to update the data when the source array is updated.
If I click on any column, my script goes to the database and brings up new sorted data. This works fine, the array is updated, the table is also updated with new data.
The problem is in the function to load more data. When I click the load more data button, the script goes to the database, brings up new data, updates the source array, but the update doesn’t reflect on the table.
Could you help me to discover my mistake?
Load more data
loadMore() {
this.setSkip(this.getSkip() + this.getLimit());
this.getData();
},
Get data
getData() {
let _token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
let url = '/api/users/get-data';
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': _token
},
body: JSON.stringify({
orderBy : this.getColumn(),
direction : this.getDirection(),
skip: this.getSkip(),
limit: this.getLimit()
})
})
//.then(response => response.json())
.then(function(response) {
return response.json();
})
.then(result => {
this.stagingData = result;
this.prepareData(this.stagingData);
})
.catch((e) => {
console.log(e);
})
},
Prepare data
prepareData(data) {
if (this.getSkip() > 0) {
this.users = [...this.users, ...data];
}
else {
this.users = data;
}
this.users.forEach(user => {
console.log(user.id + '-' + user.name);
});
},
Blade template
<div class="table-responsive overlay-scrollbars" x-data="dataTable()" x-cloak>
<x-table.table>
<x-table.table-head>
</x-table.table-head>
<x-table.table-body class="list" id="table-users-body">
<template x-for="user in users" :key="user.id">
<x-table.table-row class="btn-reveal-trigger">
<x-table.table-body-td class="id">
<a href="#" class="" data-bs-toggle="modal" data-bs-target="#form-user" @click="$dispatch('edituser', user.id)" x-text="user.id">
</a>
</x-table.table-body-td>
<x-table.table-body-td class="name white-space-nowrap">
<div class="d-flex d-flex align-items-center">
<h5 class="mb-0 fs--1" x-text="user.name"></h5>
</div>
</x-table.table-body-td>
</x-table.table-row>
</template>
</x-table.table-body>
</x-table.table>
</div>
All js (alpine) code
function dataTable() {
return {
orderByColumn: 'created_at',
directionColumn: 'desc',
stagingData: '',
users: '',
data: '',
limit: 3,
skip: 0,
init() {
this.data = @json($users);
this.users = this.data.data;
},
getSkip() {
return this.skip;
},
setSkip(val) {
this.skip = val;
},
getLimit() {
return this.limit;
},
setLimit(val) {
this.limit = val;
},
getColumn() {
return this.orderByColumn;
},
setColumn(val) {
this.orderByColumn = val;
},
setDirection(val) {
this.directionColumn = val;
},
getDirection() {
return this.directionColumn;
},
toggleDirection(val) {
let column = document.querySelector('.' + this.getColumn());
column.classList.remove('desc');
column.classList.remove('asc');
column.classList.add('sort');
this.setColumn(val);
if (this.getDirection() == 'desc') {
let newColumn = document.querySelector('.' + val);
newColumn.classList.remove('desc');
newColumn.classList.remove('sort');
newColumn.classList.add('asc')
this.setDirection('asc');
}
else {
let newColumn = document.querySelector('.' + val);
newColumn.classList.remove('asc');
newColumn.classList.remove('sort');
newColumn.classList.add('desc');
this.setDirection('desc');
}
},
orderBy(column) {
this.toggleDirection(column);
this.getData();
},
getData() {
let _token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
let url = '/api/users/get-data';
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': _token
},
body: JSON.stringify({
orderBy : this.getColumn(),
direction : this.getDirection(),
skip: this.getSkip(),
limit: this.getLimit()
})
})
//.then(response => response.json())
.then(function(response) {
return response.json();
})
.then(result => {
this.stagingData = result;
this.prepareData(this.stagingData);
})
.catch((e) => {
console.log(e);
})
},
loadMore() {
this.setSkip(this.getSkip() + this.getLimit());
this.getData();
},
prepareData(data) {
if (this.getSkip() > 0) {
// Array.prototype.push.apply(this.users, data);
// this.users.push(...data);
// this.users = arr3;
this.users = [...this.users, ...data];
}
else {
this.users = data;
}
this.users.forEach(user => {
console.log(user.id + '-' + user.name);
});
},
}
}