0
votes

I have a mat-table with sort and paginator. my component looks like this , as in ngOnInit I register to an event handler which calls the populateAlertTableSource fucntion. When this function is called, the data is indeed refreshed in the table, but the painator isn't, unless I hover my mouse over the table(or clicking on the paginator). this happens when I delete a row from the table as well - the row does not disappear and paginator does not refresh until I hover my mouse over the table(or clicking on the paginator). when I manually populate the data source on its declaration, this does not seem to happen and the pagiantor updates on the spot.

export class SomeComponent implements OnInit {

  AlertsCollection: any = [];
  alertsDataSource = new MatTableDataSource(this.AlertsCollection);
  @ViewChild('AlertsMatSort') alertSort: MatSort;
  @ViewChild("AlertsPaginator") paginator: MatPaginator;

  constructor(private alertsService: AlertsService, private alertsHubService: AlertsHubService,
    private changeDetectorRefs: ChangeDetectorRef, private modalService: NgbModal) {}


  ngOnInit() {
    this.alertsHubService.subscribe(utils.url_root);
    this.alertNotificationProxy = this.alertsHubService.generateProxy();
    this.alertsService.registerProxy(this.alertNotificationProxy, 'updateDashboard', (message: any[]) => {
      this.populateAlertTableSource(message)
    });
  }

  ngAfterViewInit() {
    this.alertsDataSource.paginator = this.paginator;
    this.alertsDataSource.sort = this.alertSort;
  }

  populateAlertTableSource(message: any) {
    this.AlertsCollection = message
    this.alertsDataSource.data = this.AlertsCollection;
    this.alertsDataSource.paginator = this.paginator;
    this.alertsDataSource.sort = this.alertSort;
    this.alertsTable.renderRows();
    this.refresh();
  }


  deleteAlert(alert: any) {
    this.alertsService.skipAlert(alert).subscribe(() => {
        var index = this.AlertsCollection.indexOf(alert, 0);
        if (index > -1)
          this.AlertsCollection.splice(index, 1);
        this.alertsDataSource.data = this.AlertsCollection;
        this.alertsTable.renderRows();
      },
      (error: AppError) => {
        console.log(error);
        throw error;
      }
    );
  }


  refresh() {
    this.changeDetectorRefs.detectChanges();
  }

}
1

1 Answers

0
votes

Difficult to say what the exact problem is without a stackblitz or something similar.

But I do recall having a similar issue a while back and what solved it for me was to set the length explicitly on your mat-paginator element in the template.

In your component:

public _alertsDataSourceLength: number;

...

populateAlertTableSource(message: any) {
    this.AlertsCollection = message
    this._alertsDataSourceLength = this.AlertsCollection.length; // new
    this.alertsDataSource.data = this.AlertsCollection;
    this.alertsDataSource.paginator = this.paginator;
    this.alertsDataSource.sort = this.alertSort;
    this.alertsTable.renderRows();
    this.refresh();
}

And in your template:

<!-- set the length explicitly -->
<mat-paginator [pageSize]="10"
               [length]="_alertsDataSourceLength"
               [pageSizeOptions]="[5, 10, 20]"
               [showFirstLastButtons]="true">
</mat-paginator>