I'm using Angular Datatables, in angular 6. My code works, I see the table I can render it. I can't search I can't control how many items get displayed, the footer says "Showing 0 to 0 of 0 entries" and "no data available in the table"
users.ts
ngOnInit() {
this.dtOptions = {
pagingType: 'full_numbers',
pageLength: 7,
deferRender: true,
retrieve: true
};
if (localStorage.getItem('data') !== null) {
const data = JSON.parse(localStorage.getItem('data'));
this.item = data.body.response;
if (Array.isArray(this.item.domains) || this.item.domains.length) {
for (let i = 0; i < this.item.domains.length; i++) {
this.users.getUsers(this.item.domains[i].id).subscribe((res: any) => {
this.domain_users = res.response.items;
// the api returns arrays and so I had to iterate over them, and not all of them
// the first array is empty
for (let j = 0; j < this.domain_users.length; j++) {
if (this.domain_users[j].user !== undefined) {
this.user.push(this.domain_users[j].user);
}
}
}, error => {
console.log('getUsers error, probably session expired on the server ' + error);
});
}
}
}
}
ngAfterViewInit(): void {
this.dtTrigger.next();
}
ngOnDestroy(): void {
// Do not forget to unsubscribe the event
this.dtTrigger.unsubscribe();
}
rerender(): void {
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
// Destroy the table first
dtInstance.destroy();
// Call the dtTrigger to rerender again
this.dtTrigger.next();
});
}
html
<table id="detailed-resource-optria" datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="compact row-border hover cell-border"
data-page-length='10'>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of user">
<td>{{item.profile?.fname}}</td>
<td>{{item.profile?.lname}}</td>
</tr>
</tbody>
</table>
I pretty much sure the problem is because I'm populating the table directly from this.user without going through dtOptions, I don't know how to fix it though, I tried supplying data from the array, as the source, that won't work.
2 Answers 2
did you try running this.dtTrigger.next(); manually after pushing all the data into this.user? as suggested here: l-lin.github.io/angular-datatables/#/basic/angular-way
(comment promoted to answer at op's request)
i'm guessing it's just a timing thing -- since your async queries weren't returning until after the ngAfterViewInit method had run, it needed an extra trigger after all data had been loaded. glad it worked :)
Comments
If you need use a large amount of Observable, use forkJoin
//define an array of observables
let request:Observable[]=[]
if (Array.isArray(this.item.domains) || this.item.domains.length) {
for (let i = 0; i < this.item.domains.length; i++){
//just fill the array of observables
request.push(this.users.getUsers(this.item.domains[i].id))
}
forkJoin(request).subscribe((response:any[])=>{
//in response[0], we have the response of getUsers(this.item.domain[0].id)
//in response[1], we have the response of getUsers(this.item.domain[1].id)
....
for (let res in response)
{
//You can use concat and filter
let users=Res.response.items
.filter(us=>us.user!=undefined)
.map(us=>us.user);
this.user.concat(users);
}
})
}
1 Comment
Explore related questions
See similar questions with these tags.
this.dtOptionsmultiple times?this.dtOptions = { ... }inside of a loop, so you create that object potentially multiple times. I don't know if it's related to your problem, but it seemed odd.this.dtTrigger.next();manually after pushing all the data intothis.user? as suggested here: l-lin.github.io/angular-datatables/#/basic/angular-waythis.dtTrigger.next();and then I did exactly as you said, it worked. Please post an answer so I can accept it