Home Reference Source Repository

src/core/interfaces/batch.js


import OlapicDevKit from '../devkit';
import OlapicUtils from '../../tools/utils';
import OlapicMediaHandler from '../entities/media/media.handler';
/**
 * The abstract class to manage entities collections, like a media feed.
 * @abstract
 */
class OlapicBatch {
    /**
     * A quick shortcut to get access to the DevKit singleton.
     * @type {OlapicDevKit}
     */
    get DevKit() {
        return OlapicDevKit.getInstance();
    }
    /**
     * The class constructor that sets the basic information for the batch, like the initial url and
     * the batch settings.
     * @param  {String}  intialUrl          - The url for the batch first page.
     * @param  {Number}  [limit=20]         - How many element per page will be fetched.
     * @param  {Boolean} [rightsOnly=false] - If this is true, it will only return entities with
     *                                        approved rights.
     */
    constructor(intialUrl, limit = 20, rightsOnly = false) {
        /**
         * The url that will be used for the next request. This will be changed by the pagination
         * methods.
         * @type {String}
         * @private
         * @ignore
         */
        this._currentUrl = intialUrl;
        /**
         * After a response it's received, this variable will store the pagination url to go
         * back a page.
         * @type {String}
         * @private
         * @ignore
         */
        this._prevUrl = '';
        /**
         * After a response it's received, this variable will store the pagination url to load
         * the next page.
         * @type {String}
         * @private
         * @ignore
         */
        this._nextUrl = '';
        /**
         * The amount of entities per page.
         * @type {Number}
         * @private
         * @ignore
         */
        this._limit = limit;
        /**
         * A flag to know if the list should only be populated with entities with rights
         * approved.
         * @type {Boolean}
         * @private
         * @ignore
         */
        this._rightsOnly = rightsOnly;
        /**
         * A flag to know if the batch it's currently fetching content.
         * @type {Boolean}
         * @private
         * @ignore
         */
        this._fetching = false;
    }
    /**
     * Makes a request to the API and returns a entities list, or an `Error` if something goes
     * wrong.
     * If this method it's called before another `fetch` promise is resolved, it will automatically
     * reject the promise with an error.
     *
     * @example
     * .fetch().then((entities) => {
     *     for (let i = 0; i < entities.length; i++) {
     *         console.log('Entity: ', entities[i].toString());
     *     }
     * }).catch((e) => console.log('Error: ', e));
     *
     * @return {Promise<Array, Error>} If everything goes well, it will return an entities list,
     *                                 otherwise, it will return an `Error`.
     */
    fetch() {
        let result = null;

        if (this._fetching) {
            result = OlapicUtils.rejectedPromise(new Error('The batch it\'s already fetching'));
        } else {
            this._fetching = true;
            const requestParameters = {
                count: this._limit,
            };

            if (this._rightsOnly) {
                // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
                requestParameters.rights_given = 1;
                // jscs:enable requireCamelCaseOrUpperCaseIdentifiers
            }

            result = this.DevKit.rest.get(this._currentUrl, requestParameters)
            .then(((response) => {
                this._fetching = false;
                const extract = OlapicMediaHandler.extractEntities(response);
                this._prevUrl = extract.links.prev ? extract.links.prev : null;
                this._nextUrl = extract.links.next ? extract.links.next : null;
                return extract.media;
            }).bind(this));
        }

        return result;
    }
    /**
     * Checks whether there's a next page to load or not.
     * @return {Boolean} Whether there's a next page or not.
     */
    hasNextPage() {
        return this._nextUrl ? true : false;
    }
    /**
     * Loads the batch next page. This method returns a call to `.fetch()`, so they can be
     * handled the same way.
     * You should always check first if there's a next page using `.hasNextPage()`.
     * @example
     * .next().then((entities) => {
     *     for (let i = 0; i < entities.length; i++) {
     *         console.log('Entity: ', entities[i].toString());
     *     }
     * }).catch((e) => console.log('Error: ', e));
     *
     * @return {Promise<Array, Error>} If everything goes well, it will return an entities list,
     *                                 otherwise, it will return an `Error`.
     */
    next() {
        this._currentUrl = this._nextUrl;
        return this.fetch();
    }
    /**
     * Checks whether there's a previous page to load or not.
     * @return {Boolean} Whether there's a previous page or not.
     */
    hasPrevPage() {
        return this._prevUrl ? true : false;
    }
    /**
     * Loads the batch previous page. This method returns a call to `.fetch()`, so they can be
     * handled the same way.
     * You should always check first if there's a previous page using `.hasPrevPage()`.
     * @example
     * .prev().then((entities) => {
     *     for (let i = 0; i < entities.length; i++) {
     *         console.log('Entity: ', entities[i].toString());
     *     }
     * }).catch((e) => console.log('Error: ', e));
     *
     * @return {Promise<Array, Error>} If everything goes well, it will return an entities list,
     *                                 otherwise, it will return an `Error`.
     */
    prev() {
        this._currentUrl = this._prevUrl;
        return this.fetch();
    }
}
/**
 * @type {OlapicBatch}
 * @module OlapicBatch
 */
export default OlapicBatch;