RXJS while loop for pagination
By using the expand
operator you can create a new Observable sequence for each value that is returned. To stop the expand
from creating any new sequences, once we get a next URL that is null, we can return an empty Observable to stop expanding our sequences. Finally, we can use a reduce
operator to aggregate the different pages of data into one array that we then emit back to the original subscriber. This can be accomplished as follows:
public getAllPeople(): Observable<Person[]> { return Observable.create(observer => { this.getPage("http://swapi.co/api/people/") .expand((data, i) => { return data.next ? this.getPage(data.next) : Observable.empty(); }) .reduce((acc, data) => { return acc.concat(data.results); }, []) .catch(error => observer.error(error)) .subscribe((people) => { observer.next(people); observer.complete(); }); });}private getPage(url: string): Observable<{next: string, results: Person[]}> { return this.http.get(url, { headers: this.headers }) .map(response => { let body = response.json(); return { next: body.next, results: body.results as Person[] }; } );}
Demo
Use expand operator like:
function getData(id) { let next = id<5 ? id+1 : null; let obj = {id:id, next:next} return next ? Rx.Observable.of(obj) : Rx.Observable.empty(); } getData(0) .expand(el=> getData(el.next)) .subscribe(x=>console.log(x));