js/models/Request/PagedRequest.js
import Request from '~/models/Request/Request';
/**
* Runs request using Axtell REST paging.
* @extends {Request}
*/
export default class PagedRequest extends Request {
/**
* The async iterator loads individual items. DO NOT
* call any other methods as that will mess up the
* page indexing.
*/
async *[Symbol.iterator]() {
let data,
page = 1,
areMore = false;
do {
({ data, areMore } = await this.getPage(page, false));
yield* data;
page += 1;
} while(areMore);
}
/**
* Runs for the next page (starts at zero).
* @return {?Object} Same type as the {@link Request#format}.
*/
async nextPage() {
this._path = `${this._sourcePath}/page/${this._page}`;
const result = await this.run({ formatted: false });
this._page += 1;
this._areMore = result.are_more;
return result.data.map(item => this.format(item));
}
/**
* Gets a specific page.
* @param {number} page - The page to load
* @param {boolean} [mutate=true] - Set to false to not
* mutate.
* @return {Object}
* @property {Object[]} data - Array of data
* @property {boolean} areMore - If there is more. If mutate
* is true, this is the same as
* doing
* {@link PagedRequest#areMore}
*/
async getPage(page, mutate = true) {
const originalPage = this._page;
const originalAreMore = this._areMore;
this._page = page;
const result = await this.nextPage();
let areMore = this.areMore;
if (mutate === false) {
this._areMore = originalAreMore;
this._page = originalPage;
}
return {
data: result,
areMore: areMore
};
}
/**
* If they are definetly more. If you haven't run a request
* this is false because we have no idea how many there are
* at the time.
* @type {boolean}
*/
get areMore() { return this._areMore || false; }
/**
* Gets the current page.
* @type {number}
*/
get page() { return this._page; }
/**
* Sets the current page. Do note this will remove all context
* but will not break iterators.
* @type {number}
*/
set page(newPage) { this._page = newPage; }
/**
* @override
* @param {Object} options - See {@link Request#constructor}
*/
constructor(options) {
super(options);
this._sourcePath = this._path;
this._page = 1;
this._areMore = null;
}
}