dimanche 28 juin 2015

Reactive javascript - convert ajax calls to Bacon.js stream with pagination

How can I convert calls to server API, with pagination support, to a Bacon.js / RxJs stream?

For the pagination I want to be able to store the last requested item-index, and ask for the next page_size items from that index to fill the stream.

But I need the 'load next page_size items' method to be called only when all items in stream already been read.

Here is a test that I wrote:

var PAGE_SIZE = 20;
var LAST_ITEM = 100;
var FIRST_ITEM = 0;

function getItemsFromServer(fromIndex) {
    if (fromIndex > LAST_ITEM) { 
        return [];
    }

    var remainingItemsCount = LAST_ITEM-fromIndex;
    if (remainingItemsCount <= PAGE_SIZE) {
        return _.range(fromIndex, fromIndex + remainingItemsCount);
    }
    return _.range(fromIndex, fromIndex + PAGE_SIZE);
}


function makeStream() {
    return Bacon.fromBinder(function(sink) {
        var fromIndex = FIRST_ITEM;

        function loadMoreItems() {
            var items = getItemsFromServer(fromIndex);
            fromIndex = fromIndex + items.length;
            return items;
        }

        var hasMoreItems = true;

        while (hasMoreItems) {
            var items = loadMoreItems();
            if (items.length < PAGE_SIZE) { hasMoreItems = false; }
            _.forEach(items, function(item) { sink(new Bacon.Next(item)); });
        }        

        return function() { console.log('done'); };
    });
}

makeStream().onValue(function(value) {
    $("#events").append($("<li>").text(value))
});

http://ift.tt/1Lw93Ba

Currently the 'getItemsFromServer' method is only a dummy and generate items locally. How to combine it with ajax call or a promise that return array of items? and can be execute unknown number of times (depends on the number of items on the server and the page size).

I read the documentation regarding Bacon.fromPromise() but couldn't manage to use it along with the pagination.

Aucun commentaire:

Enregistrer un commentaire