I retrieve around 1600 ads via an API and I would like to use a mat paginator to do the pagination without using a mat table (I use cards that I created), I filter the data with several filters that I manage directly in TypeScript.
The filter works well, the paginator too but when I launch my page the data is not displayed I have to trigger the data by activating a filter for example by selecting a country or by typing a letter in the search bar. To temporarily resolve the problem I use a setTimeOut to add a space and remove it but this does not have a viable solution. Here is my code.
I'm on Angular 16.1.6 and Angular Material 16.1.6
HTML
<!--Offer Card-->
<div class="list">
<div class="list-advert">
<app-offer-card
*ngFor="let simplifiedAdvertElement of adverts | async"
[simplifiedAdvert]="simplifiedAdvertElement"
></app-offer-card>
</div>
</div>
</div>
<mat-paginator
class="my-paginator"
*ngIf="dataSource.data.length > 0"
[pageSizeOptions]="[10, 20, 50]"
showFirstLastButtons
[length]="dataSource.data.length"
[pageSize]="pageSize"
[pageIndex]="pageIndex"
(page)="onPageChange()"
>
</mat-paginator>
TypeScript
@ViewChild(MatPaginator, {static: false})set paginator(value: MatPaginator) {
if (this.dataSource) {
this.dataSource.paginator = value;
this.initPaginator(value) //Initializes the paginator table based on the language
}
private initObservable(): void {
const formValueToObservable = (control: AbstractControl) => {
return control.valueChanges.pipe(
startWith(control.value),
tap(() => this.sendInUrl())
);
};
const search$ = formValueToObservable(this.searchCrl);
const countries$ = formValueToObservable(this.countriesCrl);
const regions$ = formValueToObservable(this.regionsCrl);
const contractType$ = formValueToObservable(this.contractTypeCrl);
const categories$ = formValueToObservable(this.categoriesCrl);
const jobFunctions$ = formValueToObservable(this.jobFunctionsCrl);
const experiences$ = formValueToObservable(this.experiencesCrl);
this.simplifiedAdvert$ = combineLatest([
this.simplifiedAdvertServices.simplifiedAdverts,
search$,
countries$ as Observable<Country[]>,
regions$ as Observable<Region[]>,
contractType$ as Observable<StandardLov[]>,
categories$ as Observable<StandardLov[]>,
jobFunctions$ as Observable<StandardLov[]>,
experiences$ as Observable<StandardLov[]>
]).pipe(
map(([simplifiedAdvert, search, countries, regions, contractType, categories, jobFunctions, experiences]) =>
simplifiedAdvert.filter((announcement: SimplifiedAdvert) =>
this.searchFilter(announcement, search) &&
this.countrySelected(announcement, countries) &&
this.regionSelected(announcement, regions) &&
this.criteriaSelected(announcement.contractType, contractType) &&
this.criteriaSelected(announcement.category, categories) &&
this.criteriaSelected(announcement.jobFunction, jobFunctions) &&
this.criteriaSelected(announcement.experience, experiences)
)
)
);
this.simplifiedAdvert$
.subscribe(data => {
this.dataSource.data = data;
this.changeDetectorRef.detectChanges();
});
this.adverts = this.dataSource.connect();
}
ngAfterViewInit(): void {
setTimeout(() => {
this.searchCrl.setValue(this.searchCrl.value + " ");
this.searchCrl.setValue(this.searchCrl.value.slice(0, -1));
}, 1500)
}