Topic: datatable pagination navigate to a particular page

ammi pro asked 2 months ago


using datatable with pagination, is it possible to select page programmatically? I tried the following code to select programmatically page 2. It produce error "Cannot read properties of undefined (reading 'pagination')".

<div class="datatable table-responsive table-hover datatable-sm" >
  <table
    class="table datatable-table"
    mdbTable
    mdbTableSort
    #table="mdbTable"
    #sortSearch="mdbTableSort"
    [dataSource]="dataSource"
    [sort]="sortSearch"
    [forceSort]="true"
    [pagination]="paginationSearch"
  >
    <thead class="datatable-header">
      <tr>
      </tr>
    </thead>
    <tbody class="datatable-body">
      <tr scope="row" *ngFor="let ps of table.data; let i=index">
         <td>   
            {{ps.date}}
        </td>
      </tr>
    </tbody>
  </table>
  <mdb-table-pagination #paginationSearch></mdb-table-pagination>
</div>

TS.

export class MyTestComponent implements OnInit {   

        @ViewChild('table') table!: MdbTableDirective<DataModel>;
        dataSource: DataModel[] = new Array<DataModel>();

    ngOnInit(): void {

        this.dataService.getData().subscribe(r => {
                    this.dataSource = r;
                    this.table.pagination.page = 2;
        });

    } 

}


Rafał Seifert staff answered 2 months ago


Please try to set the page number in AfterViewInit hook:

ngAfterViewInit(): void {
    this.table.pagination.page = 1;
  }

In OnInit hook pagination and table components are not available yet.


ammi pro commented 2 months ago

Thank you for quick reply. It didn't help. The same error. TypeError: Cannot read properties of undefined (reading 'pagination')\n at MyTestComponent.ngAfterViewInit (http://localhost:4200/main.js:93999:20)


Rafał Seifert staff commented 2 months ago

Do you have any *ngIf added to table or pagination component elements? It's strange that component is not available for you in AfterViewInit. You can try to add static: true or static: false to ViewChild decorator. Did you try to access the table and pagination components at other stages that init? Can you create a button with click listener and try to console.log(this.table.pagination)?


ammi pro commented 2 months ago

if I add timer, it works.

ngAfterViewInit(): void { setTimeout(() => { this.table.pagination = 2; } }, 5000);

However, it opens the other issues. 1. If I chose value less than 5000 it does not work. It shows the same error. 2. when it works, It shows in pagination page 2, but table presents data from page 0.


Rafał Seifert staff commented 2 months ago

Try placing the code in setTimeout with 0ms. After changing the page:this.table.pagination = 2add this method to update the data:this.table._updateData()

It should rerender data in the table. It's our inner method but it's needed in your case to work. Let me know if that helps you.


ammi pro commented 2 months ago

if I replace code with 0ms, it comes back with this.table is undefined. Data comes from API and it is relatively slow. 5000ms works, but if dataset will be larger it may stop working I guess.

this.table._updateData() - fixed an issue with displaying incorrect data.
Now, it loads data, page 0 is presented and then after 5000ms in jumps to page 2. Goal is to show page 2 from the beginning.


Rafał Seifert staff commented 2 months ago

Do you want to set page 2 from the beggining, even when table's data is empty? I am not sure if that will work without any data.

Have you thought of using some of the Higher-Order RxJs Mapping Operators like concatMap to _updateTable() only after you receive the data from the API? You should be able to do that without setting some static setTimeout timer but rather react to data comming from the server.


ammi pro commented 2 months ago

Let me explain what I am trying to do. Table is loaded with data which may occupy multiple pages. User click on the row and it will navigate him to a different component. At that time, I am saving values table.pagination.entries and table.pagination.page, so when user navigates back to table I need to take him to a page where he click the row. Since I save all filters that user selected, number of rows should be the same.


Rafał Seifert staff commented 2 months ago

So when user navigates back do you send another API request for data or do you store the data loaded previously so when he navigates back the data is there and you want to set correct table state on init? Combination of setTimeout, setting entries and page properties and then calling _updateData() should be enough to achieve such action. You can add if (this.pagination) check to avoid undefined error.


ammi pro commented 2 months ago

Yes, when user navigates back I send another API request. setTimeout to 5000 in ngAfterViewInit() works so far, but user experience is not great. User sees page 0 first and in a second it jumps to the correct page.


Rafał Seifert staff commented 2 months ago

We have async data example in our docs. With such code in our demo it just works:

ngOnInit(): void { this.dataSource$ = this._http.get(this.dataUrl).pipe( delay(7000), tap(() => { this.loading = false; this.asyncTable.pagination.page = 2; }) ); }

It's understandable that it shows page 0 on init while you are collecting the data. To improve the UX experience you can add a spinning loader.


ammi pro commented 2 months ago

I will give it a try. Thank you for your help.



Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue

  • ForumUser: Pro
  • Premium support: No
  • Technology: MDB Angular
  • MDB Version: MDB5 5.2.0
  • Device: laptop
  • Browser: Chrome
  • OS: W10
  • Provided sample code: No
  • Provided link: No