Connect mat paginator with huge API datasource and filters

47 views Asked by At

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)
}
0

There are 0 answers