1

This function can paginate an array of items:

function paginate(res,page,page_size,max_page_size) {
        page=page||1;
        page_size=page_size||10;
        max_page_size=max_page_size||100;
        page_size=page_size>max_page_size?max_page_size:page_size;
        var pages=Math.round( res.length / page_size),
            items=[];
        for( var p=1; p <= pages; p++) {
            var start= Math.round( page_size * (p-1) );
            items.push( res.slice(start,start+page_size) );
        }
        return page < items.length?items[page-1]:items[ items.length-1 ];
    }

having

  • res = array
  • page = current page
  • page_size = number of items to be returned in a page
  • max_page_size = max number of items for page

function paginate(res, page, page_size, max_page_size) {
  page = page || 1;
  page_size = page_size || 10;
  max_page_size = max_page_size || 100;
  page_size = page_size > max_page_size ? max_page_size : page_size;
  var pages = Math.round(res.length / page_size),
    items = [];
  for (var p = 1; p <= pages; p++) {
    var start = Math.round(page_size * (p - 1));
    items.push(res.slice(start, start + page_size));
  }
  return page < items.length ? items[page - 1] : items[items.length - 1];
}

var list = Array.apply(null, Array(10)).map(function() {
  return Array.apply(null, Array(Math.floor(Math.random() * 10 + 3))).map(function() {
    return String.fromCharCode(Math.floor(Math.random() * (123 - 97) + 97));
  }).join('')
});

console.log(list)
for (var i = 1; i < 8; i++) {
  console.log("page", i, paginate(list, i, 2, 2))
}

This function has a bug, since as soon as it reaches the last paginated result, it returns always the same page. Why? Is there an alternative solution?

[UPDATE]

The issue was in the indexes calculation, this is the right version:

 function paginate(res,page,page_size,max_page_size) {
    page=page||1;
    page_size=page_size||10;
    max_page_size=max_page_size||100;
    page_size=page_size>max_page_size?max_page_size:page_size;
    var pages=Math.ceil( res.length / page_size),
        items=[];
    for( var p=1; p <= pages; p++) {
        var start= page_size * (p-1)
        items.push( res.slice(start,start+page_size) );
    }
    return page <= items.length?items[page-1]:[];
}

There were 2 errors: Math.round instead of Math.ceil and the last ternary operator page <= items.length?items[page-1]:[];

6
  • Are you referring to your last for-loop? The console.log("page", i, paginate(list, i, 2, 2))? Commented Sep 21, 2017 at 14:12
  • @Matt if you see the index max value was set to 8 with 2 results for page, so you can see that, starting from the fifth element (we have 10 elements in the list), all the other three results are the same in the page. Commented Sep 21, 2017 at 14:15
  • Change for (var i = 1; i < 8; i++) to for (var i = 1; i <= list.length/2; i++) Commented Sep 21, 2017 at 14:16
  • 1
    @matt nope the problem is in the function, try like console.log(paginate(list, 5, 2, 2)) and console.log(paginate(list, 6, 2, 2)), you will get always the same values. Commented Sep 21, 2017 at 14:17
  • Your return is told to give you back the last index of items for anything larger than items.length which is 5. If you ask for page 5+, it will give you the last page which is 5 ( items[4]). What are you expecting to return for paginate(list, 6, 2, 2)? Commented Sep 21, 2017 at 14:57

1 Answer 1

1

Haven't identified the exact issue with your code yet, but I remember struggling alot with keeping state and resetting the index when I reached the end of the array while using rounding functions.

In the end I just made a 'chunker' to divide an array into chunks and hooked that up to something that rendered the array contents using the previous() and next() methods to grab the correct art of the array. Which page it actualy represents in the view, is up to the view to cache.

var Chunker = function Chunker( config ) {
        if ( !Array.isArray( config.data ) ) {
            throw new Error('chunker source is not an array');
            return false;
        }
        this.data = config.data;
        this.index = 0;
        this.length = config.len || config.data.length; // Amount of items per chunk. When not defined, will return the entire array.
    };
Chunker.prototype = {
    'constructor' : Chunker,
    'index' : function index( number ) { // => current index (getter) || => this (setter)
        if ( number !== undefined ) {
            this.index = index;
            return this;
        }
        else return this.index;
    },
    'current' : function current() { // => { "index", "data" }
        return {
            "index" : this.index,
            "data" : this.data.slice( this.index, this.index + this.length )
        };
    },
    'next' : function next() { // => next chunk
        this.index += this.length;
        if ( this.index > this.data.length ) this.index = this.data.length - (this.data.length % this.length);
        return this.current();
    },
    'previous' : function previous() { // => previous chunk
        this.index -= this.length;
        if (this.index < 0 ) this.index = 0;
        return this.current();
    },
    'reset' : function reset() { // => this
        this.index(0);
        return this;
    }
};   
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.