Skip to content

Add Pagination to Angular App

Tyler Ruff edited this page Jun 28, 2022 · 1 revision

In this example, we are using Firebase as our data store. However, the process can also be adapted to accommodate any data store.

  1. First, install Angular Material
ng add @angular/material
  1. Import the Paginator Module (in app.module.ts)
...
import { MatPaginatorModule } from '@angular/material/paginator';
...
imports: [
MatPaginatorModule,
...
  1. Next, get to work on component script (component.ts file)
...
import { Firestore, collectionData, collection, limit, query, startAt, orderBy, getDocs } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
import { PageEvent } from '@angular/material/paginator';
...
export class ExampleComponent implements OnInit {
  perPage: number = 3;
  pageNumber: number = 0;
  totalLength: number = 0;
  projects$: Observable<Project[]>;
  lastTitle: string = "";
  
  constructor(public firestore: Firestore) {
    this.projects$ = new Observable<Project[]>();
    this.getItems();
  }
  // This function is called whenever
  // the page index or item limit changes.
  public cyclePage(event:PageEvent): PageEvent{
    this.pageNumber = event.pageIndex;
    this.perPage = event.pageSize;
    this.getItems();
    return event;
  }
  
  // This function is called by the
  // constructor as well as the "cyclePage"
  // function.
  async getItems(){
    // Get total count
    let e: any = collection(this.firestore, "portfolio");
    const totalSnap = await getDocs(e);
    this.totalLength = totalSnap.size + 1;
	
	// Get item list
    if(this.pageNumber === 0){
	  // Query on first page only
      let table: any = query(collection(this.firestore, 'portfolio'), orderBy("title"), limit(this.perPage));
      this.projects$ = collectionData(table);
    } else {
	  // Query on all other pages
      let table: any = query(collection(this.firestore, 'portfolio'), orderBy("title"), limit(this.perPage * (this.pageNumber + 1)));
      const snapShot = await getDocs(table);
      let i = 0;
      snapShot.forEach((doc) => {
        const data: any = doc.data();
        if(i === ((this.perPage * this.pageNumber) - 1)){
          //console.log(data.title);
          //this.lastTitle = data.title;
          let table: any = query(collection(this.firestore, 'portfolio'), orderBy("title"), limit(this.perPage), startAt(data.title));
          this.projects$ = collectionData(table);
        }
        i++;
      })
    }
  }
  
  ngOnInit(): void { }
}
  1. Finally, let's add the paginator component to our HTML (component.html file)
...
<mat-paginator [length]="totalLength"
                [pageSize]="perPage"
                [pageIndex]="pageNumber"
                [pageSizeOptions]="[3, 5, 10, 20]"
                aria-label="Select page"
                (page)="cyclePage($event)">
</mat-paginator>
...

Sources

Clone this wiki locally