I am working on a angular application which will get the data with HTTP GET API call and load the same in a table. For data state management I am using NgRx. The data is loading fine in the table and I am able to load the same with angular material table. But the material pagination is not working properly.
I have tried multiple steps to resolve this issue like,
- adding the paginator using @ViewChild,
- in @ViewChild check if the dataSource is not undefine
- With the ChangeDetectorRef to detect changes after setting dataSource
But still it is not working as expected.
Any help will be highly appreciated.
home.component.ts
import {
AfterViewInit,
ChangeDetectorRef,
Component,
OnChanges,
OnInit,
SimpleChanges,
ViewChild,
} from '@angular/core';
import { Store } from '@ngrx/store';
import { Coffee } from '../models/coffee.model';
import { getCoffee } from '../store/actions/coffee.action';
import { CoffeState } from '../store/reducers/coffee.reducer';
import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { flatMap, Subject, takeUntil } from 'rxjs';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css'],
})
export class HomeComponent implements OnInit {
coffees: Coffee[] = [];
coffeeData$: any;
displayedColumns = [
'id',
'uid',
'blend_name',
'origin',
'variety',
'notes',
'intensifier',
];
dataSource!: MatTableDataSource<Coffee>;
//paginator!: MatPaginator;
//@ViewChild(MatPaginator, { static: false }) paginator!: MatPaginator;
@ViewChild(MatPaginator, { static: false })
set paginator(value: MatPaginator) {
if (this.dataSource) {
this.dataSource.paginator = value;
}
}
constructor(
private store: Store<CoffeState>,
private cdr: ChangeDetectorRef
) {}
ngOnInit(): void {
this.getAllCoffees();
//this.coffeeData$ = this.store.select(`coffees`);
this.coffeeData$ = this.store.select((store) => store.coffees);
console.log('this.coffeeData$ ', this.coffeeData$);
this.dataSource = this.coffeeData$;
this.cdr.detectChanges();
}
getAllCoffees() {
this.store.dispatch(getCoffee());
}
}
home.component.html
<div class="container">
<div class="example-header">
<h2 class="header-text">Coffee App</h2>
</div>
<div class="example-container mat-elevation-z8">
<mat-paginator
[pageSizeOptions]="[10, 25, 50]"
aria-label="Select page of coffees"
></mat-paginator>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<!-- ID Column -->
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef>No</th>
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
</ng-container>
<ng-container matColumnDef="uid">
<th mat-header-cell *matHeaderCellDef>User Id</th>
<td mat-cell *matCellDef="let element">{{ element.uid }}</td>
</ng-container>
<ng-container matColumnDef="blend_name">
<th mat-header-cell *matHeaderCellDef>Blend Name</th>
<td mat-cell *matCellDef="let element">{{ element.blend_name }}</td>
</ng-container>
<ng-container matColumnDef="origin">
<th mat-header-cell *matHeaderCellDef>Origin</th>
<td mat-cell *matCellDef="let element">{{ element.origin }}</td>
</ng-container>
<ng-container matColumnDef="variety">
<th mat-header-cell *matHeaderCellDef>Variety</th>
<td mat-cell *matCellDef="let element">{{ element.variety }}</td>
</ng-container>
<ng-container matColumnDef="notes">
<th mat-header-cell *matHeaderCellDef>Notes</th>
<td mat-cell *matCellDef="let element">{{ element.notes }}</td>
</ng-container>
<ng-container matColumnDef="intensifier">
<th mat-header-cell *matHeaderCellDef>Intensifier</th>
<td mat-cell *matCellDef="let element">{{ element.intensifier }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
</div>
</div>
this.dataSource needs to be an instance of MatTableDataSource, I would suggest to re-wite the onInit logic like this