Skip to content

Commit 61de2d8

Browse files
authored
Update pagination (typicode#346)
1 parent 95f1dc3 commit 61de2d8

File tree

4 files changed

+136
-3
lines changed

4 files changed

+136
-3
lines changed

src/server/router/plural.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ module.exports = function (db, name) {
3232
})
3333
}
3434

35+
function getFullURL (req) {
36+
return req.protocol + '://' + req.get('host') + req.originalUrl
37+
}
38+
3539
// GET /name
3640
// GET /name?q=
3741
// GET /name?attr=&attr=
@@ -156,8 +160,28 @@ module.exports = function (db, name) {
156160
_page = parseInt(_page, 10)
157161
_page = _page >= 1 ? _page : 1
158162
_limit = parseInt(_limit, 10) || 10
159-
_start = (_page - 1) * _limit
160-
chain = chain.slice(_start, _start + _limit)
163+
var page = utils.getPage(chain.value(), _page, _limit)
164+
var links = {}
165+
var fullURL = getFullURL(req)
166+
167+
if (page.first) {
168+
links.first = fullURL.replace('page=' + page.current, 'page=' + page.first)
169+
}
170+
171+
if (page.prev) {
172+
links.prev = fullURL.replace('page=' + page.current, 'page=' + page.prev)
173+
}
174+
175+
if (page.next) {
176+
links.next = fullURL.replace('page=' + page.current, 'page=' + page.next)
177+
}
178+
179+
if (page.last) {
180+
links.last = fullURL.replace('page=' + page.current, 'page=' + page.last)
181+
}
182+
183+
res.links(links)
184+
chain = _.chain(page.items)
161185
} else if (_end) {
162186
_start = parseInt(_start, 10) || 0
163187
_end = parseInt(_end, 10)

src/server/utils.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module.exports = {
2-
toNative: toNative
2+
toNative: toNative,
3+
getPage: getPage
34
}
45

56
// Turns string to native.
@@ -22,3 +23,30 @@ function toNative (value) {
2223
}
2324
return value
2425
}
26+
27+
function getPage (array, page, perPage) {
28+
var obj = {}
29+
var start = (page - 1) * perPage
30+
var end = page * perPage
31+
32+
obj.items = array.slice(start, end)
33+
if (obj.items.length === 0) {
34+
return obj
35+
}
36+
37+
if (page > 1) {
38+
obj.prev = page - 1
39+
}
40+
41+
if (end < array.length) {
42+
obj.next = page + 1
43+
}
44+
45+
if (obj.items.length !== array.length) {
46+
obj.current = page
47+
obj.first = 1
48+
obj.last = Math.ceil(array.length / perPage)
49+
}
50+
51+
return obj
52+
}

test/server/plural.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,17 @@ describe('Server', function () {
270270
it('should paginate with a custom limit', function (done) {
271271
request(server)
272272
.get('/list?_page=2&_limit=1')
273+
.set('host', 'localhost')
273274
.expect('Content-Type', /json/)
274275
.expect('x-total-count', db.list.length.toString())
276+
.expect('link',
277+
[
278+
'<http://localhost/list?_page=1&_limit=1>; rel="first"',
279+
'<http://localhost/list?_page=1&_limit=1>; rel="prev"',
280+
'<http://localhost/list?_page=3&_limit=1>; rel="next"',
281+
'<http://localhost/list?_page=15&_limit=1>; rel="last"'
282+
].join(', ')
283+
)
275284
.expect('Access-Control-Expose-Headers', 'X-Total-Count')
276285
.expect(db.list.slice(1, 2))
277286
.expect(200, done)

test/server/utils.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,76 @@ describe('utils', function () {
2121
assert.strictEqual(utils.toNative(true), true)
2222
})
2323
})
24+
25+
describe('getPage', function () {
26+
var array = [1, 2, 3, 4, 5]
27+
var perPage = 2
28+
29+
it('should return first page', function () {
30+
assert.deepEqual(
31+
utils.getPage(array, 1, perPage),
32+
{
33+
items: [1, 2],
34+
current: 1,
35+
first: 1,
36+
next: 2,
37+
last: 3
38+
}
39+
)
40+
})
41+
42+
it('should return second page', function () {
43+
assert.deepEqual(
44+
utils.getPage(array, 2, perPage),
45+
{
46+
items: [3, 4],
47+
current: 2,
48+
first: 1,
49+
prev: 1,
50+
next: 3,
51+
last: 3
52+
}
53+
)
54+
})
55+
56+
it('should return third page (last)', function () {
57+
assert.deepEqual(
58+
utils.getPage(array, 3, perPage),
59+
{
60+
items: [5],
61+
current: 3,
62+
first: 1,
63+
prev: 2,
64+
last: 3
65+
}
66+
)
67+
})
68+
69+
it('should return an empty array if page is greater than the last page', function () {
70+
assert.deepEqual(
71+
utils.getPage(array, 99, perPage),
72+
{
73+
items: []
74+
}
75+
)
76+
})
77+
78+
it('should return the array if perPage is greater than the array size', function () {
79+
assert.deepEqual(
80+
utils.getPage(array, 1, 99),
81+
{
82+
items: array
83+
}
84+
)
85+
})
86+
87+
it('should return an empty array if the array is empty', function () {
88+
assert.deepEqual(
89+
utils.getPage([], 1, 1),
90+
{
91+
items: []
92+
}
93+
)
94+
})
95+
})
2496
})

0 commit comments

Comments
 (0)