javascripthtmlcssangularweb

Angular Previous page button getting disabled when the next page button gets clicked


Hi I am new to angular and I am trying to implement pagination in my api and ui both I have tested and integrated the pagination in my api but bot able to implement pagination correctly in my UI. So I am stuck when I am clicking on next page button I am not able to navigate to my previous page and on first page it shows 1/2 (dealing with a db with only 2 entries right now) but when I click on next page it shows 1/1 and the next record loads and my previous button gets disabled.

This is my html file

<mat-paginator #paginator
   (page)="loadPage($event)"
   [length]="length"
   [pageSize]="pageSize"
   [disabled]="disabled" 
   [showFirstLastButtons]="showFirstLastButtons"
   [pageSizeOptions]="showPageSizeOptions ? pageSizeOptions : []"
   [hidePageSize]="hidePageSize"
   [pageIndex]="currentPage"
   aria-label="Select page">
</mat-paginator>

This is my component.ts file

import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { NewPatientComponent } from 'src/app/core/dialogs/new-patient/new-patient.component';
import { PatientVisitComponent } from 'src/app/core/dialogs/patient-visit/patient-visit.component';
import { PatientService } from 'src/app/core/service/patient/patient.service';
import { AbhaRegistrationComponent } from '../abha-registration/abha-registration.component';
import { Router } from '@angular/router';
import { ActivatedRoute } from '@angular/router';
import { MatPaginator, PageEvent } from '@angular/material/paginator';
import { MatTableDataSource } from '@angular/material/table';

@Component({
  selector: 'app-patient',
  templateUrl: './patient.component.html',
  styleUrls: ['./patient.component.css'],
})
export class PatientComponent implements AfterViewInit {
  pageSize = 1;
  length = 0;
  pageIndex = 0;
  pageSizeOptions = [5, 10, 25];
  currentPage = 0;

  hidePageSize = false;
  showPageSizeOptions = true;
  showFirstLastButtons = true;
  disabled = false;

  tableColumns: string[] = ['id', 'name', 'address', 'dateOfBirth', 'actions'];
  selectedPatient: any;
  public dataSource = new MatTableDataSource<any>([]);

  @ViewChild(MatPaginator) private paginator: MatPaginator;

  constructor(
    private dialog: MatDialog,
    private patientService: PatientService,
    private router: Router,
    private route: ActivatedRoute
  ) {}

  ngAfterViewInit(): void {
    this.getAllPatients();
    this.dataSource.paginator = this.paginator;
  }

  loadPage(event: PageEvent): void {
    if (event.pageIndex > this.currentPage) {
      // Navigating to the next page
      this.currentPage = event.pageIndex;
    } else if (event.pageIndex < this.currentPage) {
      // Navigating to the previous page
      this.currentPage = event.pageIndex;
    }

    this.pageSize = event.pageSize;
    this.getAllPatients();
  }

  getAllPatients() {
    this.patientService
      .getAllPatients(this.currentPage, this.pageSize)
      .subscribe(
        (res) => {
          if (res && res.content) {
            this.dataSource.data = res.content;
            this.length = res.totalElements;
          } else {
            console.error('API response is missing expected data:', res);
          }
        },
        (err) => {
          console.error('Error getting patients:', err);
        }
      );
  }

  newPatientDialog() {
    this.dialog.open(NewPatientComponent).afterClosed().subscribe((res) => {
      this.getAllPatients();
    });
  }

  openVisitDialog(patient: any) {
    this.dialog.open(PatientVisitComponent, {
      data: patient,
    });
  }

  openAbhaDialog(patient: any) {
    this.router.navigateByUrl('/abha', { state: patient });
  }

  applyFilter(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
    this.dataSource.filter = filterValue;
    this.dataSource.filterPredicate = this.customFilterPredicate();
  }

  customFilterPredicate() {
    return (data: any, filter: string) => {
      const name = `${data.firstName} `.toLowerCase();
      return name.includes(filter);
    };
  }
}

Solution

  • Hard to say, what goes wrong without knowing backend side. But maybe I can give you a hint, that may solve your problem.

    When switching pages you call loadPage() and in there you call getAllPatients(). There you are setting this.length = res.totalElements;. Are you sure that your API response for totalElements is NOT 1 on your second page? I suppose this would result in only having one page left on your paginator.

    Offtopic: In loadPage() instead of

       if (event.pageIndex > this.currentPage) {
          // Navigating to the next page
          this.currentPage = event.pageIndex;
        } else if (event.pageIndex < this.currentPage) {
          // Navigating to the previous page
          this.currentPage = event.pageIndex;
        }
    

    you can just write this.currentPage = event.pageIndex;. The if/else statement is senseless here.