2

I'm building a component. It's a simple list with pagination that fetches data from a webservice. I'm using bootstrap to list the values and ngx-bootstrap pagination component.

The issue is that the currentPage property is not working properly. The value is attatched to the variable, but the component is displaying the wrong info.

wrong page enter image description here

Inside the component, the variables have the @Input decorator

 @Input() listFields?: string[]; //list of displayable fields in the list
 @Input() resourceService: ResourceService<T>; //webservice to fetch data
 @Input() pageSize ?: number; //number of items to receive from the webservice
 @Input() currentPage ?: number = 1; //current page
 @Input() modelParams?: HttpParams; //other parameters to send to the webservice

The variables described above are sent to the pagination component from ngx-bootstrap.

<pagination [(itemsPerPage)]="pageSize" [(ngModel)]="currentPage" [(totalItems)]="page.totalCount" 
  (pageChanged)="pageChanged($event)"></pagination>

The component I'm developing receives the values from the @inputs as described below.

<general-resource-list 
          [resourceService]="workshopService" 
          [listFields]="listFieldsWorkshop"
          [currentPage]="currentPage"
          [pageSize]="pageSize"
          [modelParams]="pageParams">
        </general-resource-list>

@Component({
  selector: 'app-workshops-list',
  templateUrl: './workshops-list.component.html',
  styleUrls: ['./workshops-list.component.scss']
})
export class WorkshopsListComponent{

  public listFieldsWorkshop = ['id','name','version'];
  public title = "Workshop List";
  public currentPage:number;
  public pageSize:number;
  public pageParams:HttpParams;

  constructor(
    public workshopService: WorkshopService,
    public workShopRoute: ActivatedRoute, 
    public workshopRouter: Router) {
      this.workShopRoute.queryParams.subscribe(params => {
      
        this.pageParams = new HttpParams();
        for(let key in params){
          if(!["page","pageSize"].includes(key)){
            this.pageParams = this.pageParams.append(key,params[key]);
          }
        }
        this.currentPage = params['page']? params['page']:1;
        this.pageSize = params['pageSize']? params['pageSize']:10;
      });
    }
}

First I tought it was because the @Input was loaded after the rendering of the component, but even if I set the value in the constructor or directly in the variable declarations it doesn't work.

P.S.: The pageSize property is working, and it's used the same as currentPage.

P.S.2: I don't think it is the case of implementing ControlValueAccessor, this should have been implemented in the ngx-bootstrap component, isn't it?

Franco Pan
  • 128
  • 2
  • 11

4 Answers4

3

This issue happened because the value of currentPage is reset to 1. The reason is, before getting the data (initially) the totalItems (here page.totalCount) is 0, and thus currentPage is reset to 1. As a simple method, you can add an *ngIf .

ie,

    <div *ngIf="page.totalCount">
<pagination [(itemsPerPage)]="pageSize" [(ngModel)]="currentPage" [(totalItems)]="page.totalCount" 
  (pageChanged)="pageChanged($event)"></pagination>
</div>

This worked for me. Hope, this will help you all.

Elsa
  • 31
  • 2
0

For anyone who is interest in using ngx-bootstrap, I have solved the problem by doing an explicit cast in the HTML markup.

[(ngModel)]="+pagination.CurrentPage"
Chota Bheem
  • 1,106
  • 1
  • 13
  • 31
0

I honestly think this is an issue introduced with Angular 6 and/or rxjs V6. Don't wanna check in detail but looking on the solution it makes sense...

constructor(private cd: ChangeDetectorRef) {...}
...
updatePageContent(event:any):void {
...
      this.cd.detectChanges();
      this.currentPage = event.page;
...}

To my understanding the update is required to tell Angular that on the UI something has been already changed. What has been changed? Well I guess Angular is out of sync with the update of the variables. Therefore any kind of change will be thrown away and the internal counter will prevail.

Updateing the component in front grants a proper handling of the variables afterwards.

Perhaps thats a workaround for some other bug or incorrect handling - but it helps :-)

LeO
  • 4,238
  • 4
  • 48
  • 88
0

For anyone who is still facing the issue. I changed

this.currentPage = 1

before the api call. I added this.currentPage = 1 in the api response. It did not worked like it should. Than I added it before api call and it worked.

Shwet
  • 1,848
  • 1
  • 24
  • 35