I want to make mat-table where I could do filtering while retrieving data through HTTP. I managed to get sorting and pagination working by using official docs example. But I have no idea how to add filtering to this example:
HTML:
<div class="example-container mat-elevation-z8">
<div class="example-loading-shade"
*ngIf="isLoadingResults || isRateLimitReached">
<mat-spinner *ngIf="isLoadingResults"></mat-spinner>
<div class="example-rate-limit-reached" *ngIf="isRateLimitReached">
GitHub's API rate limit has been reached. It will be reset in one minute.
</div>
</div>
<div class="example-table-container">
<table mat-table [dataSource]="filteredAndPagedIssues" class="example-table" matSort
matSortActive="created" matSortDisableClear matSortDirection="desc"
(matSortChange)="resetPaging()">
<!-- Number Column -->
<ng-container matColumnDef="number">
<th mat-header-cell *matHeaderCellDef>#</th>
<td mat-cell *matCellDef="let row">{{row.number}}</td>
</ng-container>
<!-- Title Column -->
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef>Title</th>
<td mat-cell *matCellDef="let row">{{row.title}}</td>
</ng-container>
<!-- State Column -->
<ng-container matColumnDef="state">
<th mat-header-cell *matHeaderCellDef>State</th>
<td mat-cell *matCellDef="let row">{{row.state}}</td>
</ng-container>
<!-- Created Column -->
<ng-container matColumnDef="created">
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear>
Created
</th>
<td mat-cell *matCellDef="let row">{{row.created_at | date}}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
<mat-paginator [length]="resultsLength" [pageSize]="30"></mat-paginator>
</div>
TS:
/**
* @title Table retrieving data through HTTP
*/
@Component({
selector: 'table-http-example',
styleUrls: ['table-http-example.css'],
templateUrl: 'table-http-example.html',
})
export class TableHttpExample implements AfterViewInit {
displayedColumns: string[] = ['created', 'state', 'number', 'title'];
exampleDatabase: ExampleHttpDatabase | null;
filteredAndPagedIssues: Observable<GithubIssue[]>;
resultsLength = 0;
isLoadingResults = true;
isRateLimitReached = false;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
constructor(private _httpClient: HttpClient) {}
ngAfterViewInit() {
this.exampleDatabase = new ExampleHttpDatabase(this._httpClient);
this.filteredAndPagedIssues = merge(this.sort.sortChange, this.paginator.page)
.pipe(
startWith({}),
switchMap(() => {
this.isLoadingResults = true;
return this.exampleDatabase!.getRepoIssues(
this.sort.active, this.sort.direction, this.paginator.pageIndex);
}),
map(data => {
// Flip flag to show that loading has finished.
this.isLoadingResults = false;
this.isRateLimitReached = false;
this.resultsLength = data.total_count;
return data.items;
}),
catchError(() => {
this.isLoadingResults = false;
// Catch if the GitHub API has reached its rate limit. Return empty data.
this.isRateLimitReached = true;
return observableOf([]);
})
);
}
resetPaging(): void {
this.paginator.pageIndex = 0;
}
}
export interface GithubApi {
items: GithubIssue[];
total_count: number;
}
export interface GithubIssue {
created_at: string;
number: string;
state: string;
title: string;
}
/** An example database that the data source uses to retrieve data for the table. */
export class ExampleHttpDatabase {
constructor(private _httpClient: HttpClient) {}
getRepoIssues(sort: string, order: string, page: number): Observable<GithubApi> {
const href = 'https://api.github.com/search/issues';
const requestUrl =
`${href}?q=repo:angular/components&sort=${sort}&order=${order}&page=${page + 1}`;
return this._httpClient.get<GithubApi>(requestUrl);
}
}
How to add filtering to this example? I was thinking to do sorting, filtering and paging only on client side to get this working, but I think if someone could solve this issues, it would be much better to do this on server side.
If you want for instance to filter based on radiobutton change you can:
<mat-radio-group (change)="filterChanged.emit($event)" [(ngModel)]="filterString">
<mat-radio-button value="A">A</mat-radio-button>
<mat-radio-button value="B">B</mat-radio-button>
</mat-radio-group>
filterString = 'A';
filterChanged = new EventEmitter<MatRadioChange>();
this.filteredAndPagedIssues = merge(this.sort.sortChange, this.paginator.page)`
to
this.filteredAndPagedIssues = merge(this.sort.sortChange, this.paginator.page, this.filterChanged)
and then you can use this.filterString
for server request.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With