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.

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

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);
         }
    })
}

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

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.