Chloe Hamilton
Chloe Hamilton

Reputation: 95

How do I paginate cards in Angular?

Im trying to make an episode guide and each episode is displayed on a card. There are 25 cards in total, displayed 6 per page. I have working Next and Previous buttons, but need to improve upon this with a pagination system that displays 6 cards per screen and you navigate using previous, 1, 2, 3 etc.

This is the code I have so far for the cards, but I really don't understand how to get the cards and pagination to work together.

<div class="container" style="margin-top: 100px;" style="padding-bottom: 100px;"> 
     
        <div class = "row">
        <div class="col-sm-4" *ngFor = "let episode of webService.episode_list | async">
        <div class="card card-block width:10rems text-white bg-danger mb3 padding-bottom: 100px">
          
            <mat-tab-group animationDuration="750ms">
                <mat-tab label="Overview"> <img class="card-img-top" src="assets/logo.png"  alt="Card image cap">
                  <div class="card-body">
                    <h5 class="card-title">Episode: <br> {{episode.name}}</h5>
                    <p class="card-text">{{episode.summary}}<br></p>
                    <div> <button mat-raised-button colour="white" [routerLink]= "['/episodes', episode._id]">Critiques</button>
                    </div>
                  </div>   
                </mat-tab>
                <mat-tab label="More Info"> <div class="card-body">
                    <h5 class="card-title">Season:</h5><p>{{episode.season}}</p>
                    <h5 class="card-text">Episode:</h5><p>{{episode.number}}</p>
                      <h5 class="card-text">First Aired:</h5><p> {{episode.airdate}}</p>
                      <h5 class="card-text">Runtime (mins):</h5><p>{{episode.runtime}}</p>
                      <h5 class="card-text">Additional Link:</h5><p>{{episode.url}}</p>
                   
                    
            
                  </div>   
                </mat-tab>
                </mat-tab-group>

              </div>
            </div>

import {ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { WebService } from './web.service';


@Component({
 selector: 'episodes',
 templateUrl: './episodes.component.html',
 styleUrls: ['./episodes.component.css'],
 changeDetection: ChangeDetectionStrategy.OnPush
})
export class EpisodesComponent { 
    constructor(private webService: WebService) {}
    
    episodeList: WebService["getEpisodes"];
    pagedList: WebService["getEpisodes"];
    breakpoint: number = 3; 
    length: number = 0;
    pageSize: number = 2;  //displaying three cards each row
    pageSizeOptions: number[] = [3, 6, 9, 12];
  
    @Input('data') episode:[];
    page: number = 1;

    ngOnInit() {
        if (sessionStorage.page) {
            this.page = sessionStorage.page;
            } 
        this.webService.getEpisodes(this.page);
        this.breakpoint = (window.innerWidth <= 800) ? 1 : 3;
        this.episodeList = this.webService.getEpisodes;
        this.length = this.episodeList.length;
     }

    nextPage() {
        this.page = Number(this.page) + 1;
        sessionStorage.page = Number(this.page);
        this.webService.getEpisodes(this.page);
       }

    previousPage() {
    if (this.page > 1) {
    this.page = Number(this.page) - 1;
    sessionStorage.page = Number(this.page);
    this.webService.getEpisodes(this.page);
    }
    }
    

    episode_list;

}  

Upvotes: 4

Views: 5376

Answers (1)

Eliseo
Eliseo

Reputation: 57961

The problem with paginators are that you need know how many items you has. If you has two variables

  length = 20;
  pageSize = 5;

You can use together |async and |slice (or if you get all the values use only | slice)

<div *ngFor="let item of $values |async 
                |slice:((paginator.pageIndex)*pageSize):
                       ((paginator.pageIndex+1)*pageSize)">
  {{item}}
</div>
<mat-paginator #paginator [length]="length"
              [pageSize]="pageSize"
              (page)="pageEvent = $event">
</mat-paginator>

See how use slice using paginator.pageIndex -"paginator" is the variable reference -the #paginator in the tag mat-paginator-)

See the example in stackblitz

NOTE: If your elements are a few, you can get all the values and store in a variable

this.dataService.getList().subscribe((res:any)=>{
   this.length=res.length;
   this.values=res;
})

And you iterate

<div *ngFor="let item of values|slice:((paginator.pageIndex)*pageSize):
                                      ((paginator.pageIndex+1)*pageSize)">

Update we can has a paginator with select options paginator also

<div *ngFor="let item of $values |async |slice:((paginator.pageIndex)*paginator.pageSize):((paginator.pageIndex+1)*paginator.pageSize)">
  {{item}}
</div>
<mat-paginator #paginator [length]="length"
              [pageSize]="pageSize"
              [pageSizeOptions]="[5, 10, 25, 100]"
              (page)="pageEvent = $event">
</mat-paginator>

Upvotes: 6

Related Questions