How can I paginate an API with a cursor using axios
? I would like to recursively call this function until response.data.length < 1
and return the entire array with all items in the collection when it is done. Also, worth noting, I would have to pass the cursor into subsequent calls.
function getUsers () {
return axios.get('/users') // API supports a cursor param (?after=)
.then(response => {
// returns an array with a cursor
// see response below
console.log(response.data)
})
}
Example response:
{
"total": 100,
"data": [
{
user: "Bob"
},
{
user: "Sue"
},
{
user: "Mary"
},
],
"pagination": {
"cursor": "lkdjsfkljsdkljfklsdjfkjsdk"
}
}
Thank you for your help in advance.
Here's a recursive function that manages the cursor from the response:
function getUsers (cursor, data = []) {
return axios.get('/users' + (cursor ? '?after='+cursor : '')) // API supports a cursor param (?after=)
.then(response => {
if (response.data.length < 1 ) return data
data.push(...response.data)
return getUsers(response.pagination.cursor, data)
})
}
// use it to get data
getUsers()
.then(data => console.log("final data", data))
This is how it might work with a faked axios
function and some extra logging to show the ordering:
// Fake axios get -- just return numbers so it's easy to test
let axios = {
data: data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
get(url) {
let cursor = parseInt(url.split('?after=')[1] || 0)
console.log("cursor:", cursor)
let ret_data = data.slice(cursor, cursor +5)
return new Promise(resolve => setTimeout(() => resolve({
"total": 15,
"data": ret_data,
"pagination": {
"cursor": cursor +5
}
}), 400)
)
}
}
function getUsers (cursor, data = []) {
return axios.get('/users' + (cursor ? '?after='+cursor : '')) // API supports a cursor param (?after=)
.then(response => {
console.log("getting data", response.data)
if (response.data.length < 1 ) return data
data.push(...response.data)
return getUsers(response.pagination.cursor, data)
})
}
getUsers()
.then(data => console.log("final data", data))
Have a separate recursive function that takes an array, gets /users
, and either pushes to the array and calls itself again, or resolves if there are no more users:
function getUsers () {
getOne()
.then((users) => {
// got all users
});
}
const getOne = (users = []) => axios.get('/users')
.then(({ data }) => {
// Resolve the promise initialized in `getUsers` with the final array:
if (data.length < 1) return users;
// Else, push to the array and chain another promise onto the end:
users.push(...data);
return getOne(users);
})