Search code examples
typescriptasp.net-coreasp.net-core-webapiasp.net-core-6.0angular13

How to pass Page Number from component.html Angular 13 to web api?


I work on a web application with ASP.NET Core 6 and Angular 13.

This application displays a list of items successfully without any issue.

My issue How to Pass Page Number from to Web Api using Angular 13?

What I tried is:

(1) Create Web API action to display all items

public async Task<IActionResult> GetAll(int pageNumber)
{
    var allitems = _iitem.GetAllItems();

    var result = _pageHelper.GetPage(allitems.AsQueryable(), pageNumber);

    var itemsdata = new ItemsPageViewModel
            {
                items = result.Items,
                Pager = result.Pager
            };

    return Ok(itemsdata);
}

When I call this action method, it returns json data as shown here:

{
    "items": [
        {
            "id": 3,
            "itemNameEN": "pen"
        },
        {
            "id": 4,
            "itemNameEN": "pencil"
        },
        {
            "id": 5,
            "itemNameEN": "pen2"
        }
    ],
    "pager": {
        "numberOfPages": 1,
        "currentPage": 1,
        "totalRecords": 3
    }
}

(2) I created a component items logic in component.ts:

ngOnInit(): void {
    this.retrieveAllItems();
  }
 
 retrieveAllItems(): void {
  this.erpservice.getAll()
    .subscribe(
      data => {
   
        this.items = data.items;
        console.log(data);
      },
      error => {
        console.log(error);
      });
}

(3) I created a component view component.html:

<table id="customers">
  <tr>
      <th>Id</th>
      <th>ItemNameEN</th>
  </tr>
  <tr *ngFor="let item of items">
      <td>{{item.id}}</td>
      <td>{{item.itemNameEN}}</td>
  </tr>
</table>

How to pass Page Number from Angular 13 to web api ?

I install ngxPagination module

and add below lines

<div class="col-md-12">
    <pagination-controls
      previousLabel="Prev"
      nextLabel="Next"
      [responsive]="true"
    ></pagination-controls>
  </div>

my issue how to pass page number from component.html to web api ?

updated post page number not display as 1 2 only display previous and next so How to display it

last updated post

i get error when apply pagination on html

optional (property) ItemsComponent.items?: ItemsData[] | undefined

error display on items collection

items.html as below

<table id="customers">
  <tr>
    <th>Id</th>
    <th>ItemNameAR</th>
    <th>ItemNameEN</th>
    <th>Description</th>
  </tr>
  <tr
    *ngFor="
      let item of items
        | paginate
          : {
              itemsPerPage: pager?.numberOfPages,
              currentPage: pager?.currentPage,
              totalItems: pager?.totalRecords
            }
    "
  >
  <td>{{item.id}}</td>
  <td>{{item.itemNameAR}}</td>
  <td>{{item.itemNameEN}}</td>
  <td>{{item.description}}</td>
  </tr>
</table>

<pagination-controls
  previousLabel="Prev"
  nextLabel="Next"
  [responsive]="true"
  (pageChange)="onPageChanged($event)" 
></pagination-controls>

items.ts

items?:ItemsData[];
 ngOnInit(): void {
    this.retrieveAllItems();
  }
  onPageChanged(pageNumber: number) {
    this.retrieveAllItems(pageNumber);
  }



retrieveAllItems(pageNumber: number = 0): void {
    this.erpservice.getAll(pageNumber)
      .subscribe(
        data => {
        this.items=data.items;
        this.pager=data.pager;

       
        },
        error => {
          console.log(error);
        });
  }

export interface ItemsData {
    id:number;
    itemNameER:string;
    itemNameAR:string;
    itemNameEN:string;
    description:string;
}

getAll(pageNumber: number): Observable<DataWrapper> {
    let params = new HttpParams();

    if (pageNumber)
      params = params.append('pageNumber', pageNumber);

    let httpOptions = {
        params: params
    };
    return this.http.get<DataWrapper>(baseUrl,httpOptions);
  }

export interface DataWrapper {
    items: ItemsData[];
    pager:Pager;
}

export interface Pager {
    numberOfPages:number;
    currentPage:number;
    totalRecords:number;
}

issue error


Solution

  • From PaginationControlsComponent documentation

    pageChange [event handler] The expression specified will be invoked whenever the page changes via a click on one of the pagination controls. The $event argument will be the number of the new page. This should be used to update the value of the currentPage variable which was passed to the PaginatePipe.

    1. Add the pageChange event to <<pagination-controls> that trigger the onPageChanged method and pass the current page value when the page is changed.
    <pagination-controls
      previousLabel="Prev"
      nextLabel="Next"
      [responsive]="true"
      (pageChange)="onPageChanged($event)" 
    ></pagination-controls>
    
    1. Implement the onPageChanged method.
    onPageChanged(pageNumber: number) {
      this.retrieveAllItems(pageNumber);
    }
    
    1. Possible that you need to modify the retrieveAllItems method signature to support the pageNumber parameter as optional.
    retrieveAllItems(pageNumber: number = 1): void {
      this.erpservice.getAll(pageNumber)
        .subscribe(...);
    }
    
    1. The getAll method in the ErpService service is also required to support the page number. Unsure what is your API URL with page number, I assume your API URL is something like:

    https://<your-domain-URL>/api/<action>/{pageNumber}

    export class ErpService {
      ...
    
      baseUrl = '<your-domain-URL>';
       
      getAll(pageNumber: number): Observable<ItemsPageViewModel> {
        // Pass the pageNumber to url. Example:
        let apiUrl = this.baseUrl + '/<action>'; // Replace <action> based on your API url
    
        if (pageNumber)
          apiUrl += `/${pageNumber}`;
    
        return this.http.get<ItemsPageViewModel>(apiUrl);
      }
    }
    

    For passing pageNumber to API as query params

    If you implement the GetAll API to retrieve pageNumber from query params

    public async Task<IActionResult> GetAll([FromQuery]int pageNumber)
    {
        ...
    }
    

    On the Angular side, you should pass the pageNumber with HttpParams.

    export class ErpService {
      ...
    
      baseUrl = '<your-domain-URL>';
       
      getAll(pageNumber: number): Observable<ItemsPageViewModel> {
        let apiUrl = this.baseUrl + '/<action>'; // Replace <action> based on your API url
    
        let params = new HttpParams();
    
        if (pageNumber)
          params = params.append('pageNumber', pageNumber);
    
        let httpOptions = {
            params: params
        };
    
        return this.http.get<ItemsPageViewModel>(apiUrl, httpOptions);
      }
    }
    

    Issue: Page Number is not showing

    You need to apply PaginatePipe as shown in this Server Paging Example | ngx-pagination.

    1. Apply PaginatePipe on items by providing info such as itemsPerPage, currentPage and totalItems.
    <tr
      *ngFor="
        let item of items
          | paginate
            : {
                itemsPerPage: itemsPerPage,
                currentPage: pager?.currentPage,
                totalItems: pager?.totalRecords
              }
      "
    >
      ...
    </tr>
    
    1. Retrieve the pager info from the API response.
    export class AppComponent {
      pager: Pager;
      itemsPerPage: number = 3;
    
      ...
    
      retrieveAllItems(pageNumber: number = 1): void {
        this.erpservice.getAll(pageNumber).subscribe(
          (data) => {
            this.items = data.items;
            this.pager = data.pager;
    
            console.log(data);
          },
          (error) => {
            console.log(error);
          }
        );
      }
    }
    

    Demo @ StackBlitz