1

In my component I am using datatables to show the data from my backend. I am able to get the data from the backend (using a service), parse it successfully and show the data in the data-table. However, my problem is that when my component is first rendered, the network call has not yet completed and hence the table is populated with "No data available in table". Once the network call completes the table gets populated with the data from the server but the message "No data available in table" is still present.

Here is my network call code -

fetchData(){
    this.networkservice.getAllReceipts()
          .subscribe(

            res => {
              this.itemList = res;
            }, error => alert(error),
            () => this.showData());
  }

I am calling this method inside the ngOnInit(). I have also tried calling this method inside the constructor as well as inside ngAfterViewChecked(), but no success.

My showData() method never gets called.

In the documentation of data-tables they have mentioned something called rerender() which can be used to re-render the table but I cant figure out where I should use it. I have it placed inside my showData() method but it never gets called.

I have also used "setTimeout" to set a timeout of 5 secs but even that doesn't seem to work.

My HTML Code-

<table id="receiptTable" [dtTrigger]="dtTrigger" datatable class="row-border hover">
  <thead>
    <tr>
      <th>ID</th>
      <th>First name</th>
      <th>LastName name</th>
      <th>Action</th>
    </tr>
  </thead>

  <tbody *ngIf="itemList">
      <tr *ngFor="let user of itemList">
        <td>{{user.id}}</td>
        <td>{{user.firstName}}</td>
        <td>{{user.lastName}}</td>
        <td><button (click)="getUser(user.id)">Edit</button></td>
      </tr>
    </tbody>
</table>

Please help.

2
  • Can you show the HTML Code too ? this.showData() will get called if observable complete is triggered. Probably in your case thats not getting triggered. Also, what are you doing in showData() , can you put that code too ? Commented Jun 12, 2017 at 4:56
  • @Skeptor - I have updated my question with my html code ... also right now in this.showData(), I just log a message (to see if its triggered). Commented Jun 12, 2017 at 15:30

5 Answers 5

1

I have tried this in angular 7 and it worked.. runtime datatable changed

.Ts file

import { Component, AfterViewInit, OnDestroy, OnInit, ViewChild } from '@angular/core';
    import { DataTableDirective } from 'angular-datatables';
    
    @Component({
      selector: 'app-selector',
      templateUrl: 'app-selector.component.html'
    })
    export class CustomRangeSearchComponent implements AfterViewInit, OnDestroy, OnInit {
      @ViewChild(DataTableDirective, {static: false})
      datatableElement: DataTableDirective;
      dtOptions: DataTables.Settings = {};
      tableData = [];
    
      ngOnInit(): void {
        this.dtOptions = {
          destroy: true,
          ordering: true,
          pagelength: 10,
          pagingType: "full_numbers",
          columnDefs: [{ 
            targets: 0,
            checkboxes:{
            selectRow: true,
            selected: true
          }]
        };
      }
    
      ngOnDestroy(): void {
        $.fn['dataTable'].ext.search.pop();
      }

      ngAfterViewInit(): void {
        this.dtTrigger.next();
      }
    
      getdata(){
    
        //... get your response
        this.tableData = response; //this should be in array

        setTimeout(() => {
          this.datatableElement.dtInstance.then((dtInstance: DataTables.Api) => {
            dtInstance.draw();
          });
        });
      }
    }

.HTML file

<button class="btn btn-primary" (click)="getData()">Filter by ID</button>
<table datatable [dtOptions]="dtOptions" class="row-border hover"></table>
Sign up to request clarification or add additional context in comments.

Comments

0

It would be better if we had more code to look at but you can also have a look here where the following additions are mentioned for the datatables-angular module usage:

// We use this trigger because fetching the list of persons can be quite long,
// thus we ensure the data is fetched before rendering
dtTrigger: Subject = new Subject();

ngOnInit(): void {
    this.http.get('data/data.json')
      .map(this.extractData)
      .subscribe(persons => {
        this.persons = persons;
        // Calling the DT trigger to manually render the table
        this.dtTrigger.next();
      });
  }

Comments

0

With your code it should work fine. This is not exactly an answer few steps to help you debug.

First make sure this.itemList is undefined or null just to be sure.

To verify if you are getting data at all , add do to debug . Change the component code to this:

this.networkservice.getAllReceipts()
    .do(res => console.log(res))
    .subscribe(
        res => {this.itemList = res},
        error => console.error(error) 
     );

As mentioned by @Giannis adding this.dtTrigger.next() should force the table to render.

Comments

0

you can use angular datatables and the link is here https://l-lin.github.io/angular-datatables/#/getting-started. just follow the steps in this documentation.

in your code add this.dtTrigger.next() after you get your data in "this.itemList". like below :

fetchData(){ this.networkservice.getAllReceipts() .subscribe(

        res => {
          this.itemList = res;
          this.dtTrigger.next();    ***## Add here ##***
        }, error => alert(error),
        () => this.showData());

}

Comments

0

Using the following in the CSS should resolve the issue

    .dataTables_empty {
      display: none;
     } 

Comments

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.