angularngx-pagination

Search or filter paginated data using StartData and EndDate in Angular


In my Angular-14 project, I am consuming an end-point from ASP.Net Core-6 Web API using JSON response.

Without Parameter, my endpoint URL from is like this:

https://localhost/MyApp/api/v1/all-merchants

While with Parameter it becomes:

https://localhost/MyApp/api/v1/all-merchants?StartDate=2022-01-01&EndDate=2023-01-01&PageNumber=2&PageSize=10

Then I have this JSON response from the Web API:

{
  "data": {
    "pageItems": [
      {
        "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "merchantName": "Jonathan Plc",
        "accountName": "Jonathan"
        "createdAt": "2022-02-02T09:54:12.513"
      }
    ],
    "currentPage": 2,
    "pageSize": 10,
    "numberOfPages": 6,
    "totalRecord": 55
    "previousPage": 1
  },
  "successful": true,
  "message": "string",
  "statusCode": 0
}

ANGULAR

I have the Angular code below

Service:

getAllMerchantsPagination(pageNumber?: number,pageSize?: number): Observable<IMerchantList[]> {
  return this.http.get<IMerchantList[]>(this.baseUrl + '/merchants/all-merchants?pagenumber='+ pageNumber+'&pageSize='+pageSize);
}

model (IMerchantList):

export interface IPageItem {
  id: string;
  merchantName: string;
  accountName: string;
  createdAt: Date
}

export interface IData {
  pageItems: IPageItem[];
  pageSize: number;
  currentPage: number;
  numberOfPages: number;
  totalRecord: number;
}

export interface IMerchantList {
  data: IData;
  successful: boolean;
  message: string;
  statusCode: number;
}

Then I have the component:

component.ts:

 allMerchantList: any[] = [];
  dataBk: IPageItem[] = this.allMerchantList;
  pageSize: number = 10;
  currentPage: number = 1;
  numberOfPages!: number;
  totalRecords: number = 0;
  pageSizes = [10, 20, 50, 100];

  loadAllMerchants() {
    this.merchantService.getAllMerchantsPagination(this.currentPage, this.pageSize).subscribe({
      next: (res: any) => {
        this.allMerchantList = res.data.pageItems;
        this.totalRecords = res.data.totalRecord;
        this.currentPage = res.data.currentPage;
        this.pageSize = res.data.pageSize;
        this.dataBk = res.data.pageItems;
      }
    })
  }

  handlePageChange(event: number): void {
    this.currentPage = event;
    this.loadAllMerchants();
  }

  handlePageSizeChange(event: any): void {
    this.pageSize = event.target.value;
    this.currentPage = 1;
    this.loadAllMerchants();
  }

component.html

<div class="row">
  <div class="col-md-6">
    <div class="form-group">
      <label for="startDate">Start Date</label>
      <div class="input-group">
        <div class="input-group-prepend">
          <span class="input-group-text"><i class="far fa-calendar-alt"></i></span>
        </div>
        <input type="text"
        bsDatepicker
        [minDate]="minStartDate"
        [bsConfig]="{ isAnimated: true, dateInputFormat: 'DD-MM-YYYY', returnFocusToInput: true, showClearButton: true, clearPosition: 'right' }">
      </div>
    </div>
  </div>
  <div class="col-md-6">
    <div class="form-group">
      <label for="endDate">End Date</label>
      <div class="input-group">
        <div class="input-group-prepend">
          <span class="input-group-text"><i class="far fa-calendar-alt"></i></span>
        </div>
        <input type="text"
        placeholder="DD-MM-YYYY"
        bsDatepicker
        [minDate]="minEndDate"
        [bsConfig]="{ isAnimated: true, dateInputFormat: 'DD-MM-YYYY', returnFocusToInput: true, showClearButton: true, clearPosition: 'right' }">
      </div>
    </div>
  </div>
</div>

<div class="card-body">
  <table class="table table-striped table-bordered table-hover">
    <thead>
      <tr>
        <th style="width: 10px">#</th>
        <th [class.active]="order === 'merchantName'" (click)="setOrder('merchantName')">Merchant Name <span [hidden]="reverse">▼</span
          ><span [hidden]="!reverse">▲</span></th>
        <th [class.active]="order === 'accountName'" (click)="setOrder('accountName')">Merchant Account Name. <span [hidden]="reverse">▼</span
          ><span [hidden]="!reverse">▲</span></th>
        <th>Status</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody *ngIf="allMerchantList != undefined">
      <tr *ngFor="let row of allMerchantList
      | paginate : {
        itemsPerPage: pageSize,
        currentPage: currentPage,
        totalItems: totalRecords
      } | orderBy: order:reverse:caseInsensitive; let i = index;">
      <td style="width: 80px">
        {{ i + 1 }}.</td>
        <td>{{ row?.merchantName || 'N/A' }}</td>
        <td>{{ row?.accountName || 'N/A' }}</td>
      </tr>
      <tr *ngIf="allMerchantList.length ==0;">
        <td colspan="7" class="text-center">
          <span class="align-center">No Data Found!</span>
        </td>
      </tr>
    </tbody>
  </table>

CreatedAt field is used as the StartDate andEndDate

With ngx-pagination, the pagination is working fine.

However, using ngx-bootstrap-datepicker, I want the user to select the StartDate and End Date, then click on the Submit button. When this is done, it should display the result on the html table shown in the code.

How do I modify my code in the service, component and html to achieve this?


Solution

  • You can send startdate and endDate like this way too.

    getAllMerchantsPagination(pageNumber?: number,pageSize?: number, startDate?: string, endDate?: string): Observable<IMerchantList[]> {
      let params = new HttpParams()
        .set('pageNumber', pageNumber?.toString() ?? '')
        .set('pageSize', pageSize?.toString() ?? '')
        .set('StartDate', startDate ?? '')
        .set('EndDate', endDate ?? '');
    
      return this.http.get<IMerchantList[]>(this.baseUrl + '/merchants/all-merchants', { params: params });
    }
    

    and in component it like

    loadAllMerchants() {
      this.merchantService.getAllMerchantsPagination(this.currentPage, this.pageSize, this.startDate, this.endDate).subscribe({
        next: (res: any) => {
          this.allMerchantList = res.data.pageItems;
          this.totalRecords = res.data.totalRecord;
          this.currentPage = res.data.currentPage;
          this.pageSize = res.data.pageSize;
          this.dataBk = res.data.pageItems;
        }
      })
    }
    

    component.html look like

    <div class="row">
      <div class="col-md-6">
        <div class="form-group">
          <label for="startDate">Start Date</label>
          <div class="input-group">
            <div class="input-group-prepend">
              <span class="input-group-text"><i class="far fa-calendar-alt"></i></span>
            </div>
            <input type="text"
            bsDatepicker
            [minDate]="minStartDate"
            [bsConfig]="{ isAnimated: true, dateInputFormat: 'DD-MM-YYYY', returnFocusToInput: true, showClearButton: true, clearPosition: 'right' }">
          </div>
        </div>
      </div>
      <div class="col-md-6">
        <div class="form-group">
          <label for="endDate">End Date</label>
          <div class="input-group">
            <div class="input-group-prepend">
              <span class="input-group-text"><i class="far fa-calendar-alt"></i></span>
            </div>
            <input type="text"
            placeholder="DD-MM-YYYY"
            bsDatepicker
            [minDate]="minEndDate"
            [bsConfig]="{ isAnimated: true, dateInputFormat: 'DD-MM-YYYY', returnFocusToInput: true, showClearButton: true, clearPosition: 'right' }">
          </div>
        </div>
      </div>
    </div>
    
    <div class="card-body">
      <table class="table table-striped table-bordered table-hover">
        <thead>
          <tr>
            <th style="width: 10px">#</th>
            <th [class.active]="order === 'merchantName'" (click)="setOrder('merchantName')">Merchant Name <span [hidden]="reverse">▼</span
              ><span [hidden]="!reverse">▲</span></th>
            <th [class.active]="order === 'accountName'" (click)="setOrder('accountName')">Merchant Account Name. <span [hidden]="reverse">▼</span
              ><span [hidden]="!reverse">▲</span></th>
            <th>Status</th>
            <th>Action</th>
          </tr>
        </thead>
        <tbody *ngIf="allMerchantList != undefined">
          <tr *ngFor="let row of allMerchantList
          | paginate : {
            itemsPerPage: pageSize,
            currentPage: currentPage,
            totalItems: totalRecords
          } | orderBy: order:reverse:caseInsensitive; let i = index;">
          <td style="width: 80px">
            {{ i + 1 }}.</td>
            <td>{{ row?.merchantName || 'N/A' }}</td>
            <td>{{ row?.accountName || 'N/A' }}</td>
          </tr>
          <tr *ngIf="allMerchantList.length ==0;">
            <td colspan="7" class="text-center">
              <span class="align-center">No Data Found!</span>
            </td>
          </tr>
        </tbody>
      </table>