2

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.

marc_s
760k185 gold badges1.4k silver badges1.5k bronze badges
asked Aug 20, 2018 at 19:07
7
  • Why do you create this.dtOptions multiple times? Commented Aug 20, 2018 at 19:20
  • You do 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. Commented Aug 20, 2018 at 19:26
  • @FrankModica Nice catch! I fixed it thank you, but it's unrelated to my question, the problem is there still Commented Aug 20, 2018 at 19:29
  • 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 Commented Aug 20, 2018 at 19:52
  • @derelict I tried it earlier didn't work, I tried it now, it worked, I just removed all existing this.dtTrigger.next(); and then I did exactly as you said, it worked. Please post an answer so I can accept it Commented Aug 20, 2018 at 19:57

2 Answers 2

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 :)

answered Aug 20, 2018 at 20:24
Sign up to request clarification or add additional context in comments.

Comments

2

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);
 }
 })
}
answered Aug 20, 2018 at 20:20

1 Comment

interesting, I had to accept his answer though since his answer solve the problem i asked. But I think your answer is more important to me,personally, regardless of the datatables, it's an improvement of the most vital piece of code in the app. Since most data are processed in the same way

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.