One way to solve this is with RxJS
We'll build a small Observable stream that will:
- Output all post data
- Not force us to know total number of posts OR pages beforehand
- Not force to keep track of "where we're at" in the context of pagination
Libraries we'll use:
- Axios (To simplify the HTTP GET, as it works both in Node and Browser environments)
- RxJS v6 (Currently an Alpha release, but the API here is the same for RxJS 5)
Your environment and use case will vary, for this example I'm going to be in a Node environment.
/**
* This will get all posts from a default WordPress REST API
* First we see how many pages there are
* Then we make subsequent XHR requests (via Axios)
* That paginate through every page of posts
*/
// Importing Axios for simple AJAX request
const axios = require('axios')
// Importing RxJS @ v6.0.0-alpha.3
const { Observable, from, range } = require('rxjs')
const { switchMap, concatMap } = require('rxjs/operators')
const endpoint = 'http://demo.wp-api.org/wp-json/wp/v2/posts'
/**
* This sets up the initial request and the Observable stream
* In the return from the endpoint, the Axios request headers will have x-wp-totalpages,
* which gives us... the total pages of posts ;)
*/
const posts$ = Rx.Observable.from(axios.get(endpoint))
/**
* We now know the total number of pages,
* so we'll switch to a new Observable that is just a range of numbers
* We'll start with 1, and end with whatever the total number of pages is
* This gives us a stream of 1--n--n--n... (example: 1, 2, 3, 4...)
*/
.switchMap((
{ headers }, // using ES6 function header destructuring and arrow functions here
) => Rx.Observable.range(1, Number(headers['x-wp-totalpages'])))
/**
* We can now paginate through all posts, getting 10/page
* concatMap will fire off a request, waits until it completes, and then fire the next one
* In each subsequent firing, we ask for the next page of posts
*/
.concatMap(page =>
axios.get(endpoint, {
params: {
page,
},
}),
)
.subscribe(
// data here is an Array of WordPress Posts, tacking .length shows us how many per page we are getting
({ data }) => console.log(data.length),
err => console.log('Oh no, an error!', err),
)
Resources