Reputation: 7138
I have simple provider and it gets data from API
url, I need help to paginate
this data and load it by IonInfiniteScroll
.
Provider
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { LoadingController } from '@ionic/angular';
@Injectable({
providedIn: 'root'
})
export class CategoriesService {
apiUrl = 'https://example.com/api/categories';
constructor(private http: HttpClient, private loadingCtrl: LoadingController) { }
getDetails(url) {
const httpOptions = {
headers: new HttpHeaders({
'Accept': 'application/json, text/plain',
'Content-Type': 'application/json'
})
};
return this.http.get(`${this.apiUrl}/${url}`, httpOptions).pipe(
map(category => category)
);
}
}
Module
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { CategoriesService } from './../../services/categories.service';
import { LoadingController } from '@ionic/angular';
@Component({
selector: 'app-categories-details',
templateUrl: './categories-details.page.html',
styleUrls: ['./categories-details.page.scss'],
})
export class CategoriesDetailsPage implements OnInit {
categories: Observable<any>;
loading: any;
constructor(
private categoriesService: CategoriesService,
public loadingController: LoadingController,
) {}
ngOnInit() {
this.getData();
}
async getData(){
this.loading = await this.loadingController.create({
message: 'Please wait...',
spinner: 'crescent',
duration: 2000
});
await this.loading.present();
this.categoriesService.getCategories().subscribe((res) => {
this.categories = res;
this.hideLoading()
});
}
private hideLoading() {
this.loading.dismiss();
}
}
Note loading: any;
current loading just show loading till page loads, it returns all posts at once, it has nothing to do with posts pagination or just loading first 10 of them.
This code currently working just fine, all I need to make sort of pagination and add scroll loading.
View
This code returns each category posts which I need to paginate (posts)
<ion-content padding>
<ion-grid>
<ion-row>
<ion-list *ngIf="category">
<ion-item *ngFor="let post of category.posts">
<ion-avatar slot="start">
<img [routerLink]="['/', 'posts', post.url]" [src]="post.image">
</ion-avatar>
<ion-label class="ion-text-wrap" [routerLink]="['/', 'posts', post.url]">{{post.title}}</ion-label>
</ion-item>
</ion-list>
</ion-row>
</ion-grid>
</ion-content>
Any idea which part should I change and how?
Upvotes: 6
Views: 14627
Reputation: 2951
Ionic 4 Infinite Scroll
https://ionicframework.com/docs/api/infinite-scroll
In home.page.html file
<ion-header>
<ion-toolbar>
<ion-title>
Ionic Blank
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-button (click)="toggleInfiniteScroll()" expand="block">
Toggle Infinite Scroll
</ion-button>
<ion-list>
<ion-item *ngFor="let item of dataList">
<ion-label>{{item}}</ion-label>
</ion-item>
</ion-list>
<ion-infinite-scroll threshold="100px" (ionInfinite)="loadData($event)">
<ion-infinite-scroll-content
loadingSpinner="bubbles"
loadingText="Loading more data...">
</ion-infinite-scroll-content>
</ion-infinite-scroll>
</ion-content>
home.page.ts
import { Component, ViewChild } from '@angular/core';
import { IonInfiniteScroll } from '@ionic/angular';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
@ViewChild(IonInfiniteScroll) infiniteScroll: IonInfiniteScroll;
dataList:any;
constructor() {
this.dataList = [];
for (let i = 0; i < 25; i++) {
this.dataList.push("Item number "+this.dataList.length);
}
}
loadData(event) {
setTimeout(() => {
console.log('Done');
for (let i = 0; i < 25; i++) {
this.dataList.push("Item number "+this.dataList.length);
}
event.target.complete();
// App logic to determine if all data is loaded
// and disable the infinite scroll
if (this.dataList.length == 1000) {
event.target.disabled = true;
}
}, 500);
}
toggleInfiniteScroll() {
this.infiniteScroll.disabled = !this.infiniteScroll.disabled;
}
}
Upvotes: 0
Reputation: 536
There is another method using your code.
this.categoriesService.getCategories().subscribe((res) => {
this.categories = res;
this.hideLoading();
this.setPage(1);
});
setPage(page: number) {
if (page < 1 || page > this.pager.totalPages) {
return;
}
// get pager object from service
this.pager = this.pagerService.getPager(this.allItems.length, page);
// get current page of items
this.pagedItems = this.allItems.slice(this.pager.startIndex, this.pager.endIndex + 1);
}
Upvotes: 0
Reputation: 109
Parameterize your getData() function to take in pageNumber and/or skip parameters, and invoke it in the (ionInfinite) output event of ion-infinite-scroll. Modify the url
variable with the pagination parameters to fetch the required data.
Also, when the total data equals the fetched data, disable infiniteScroll.
Upvotes: 0