Skip to content

Commit b7f041c

Browse files
committed
New pagination API & service getters tested
1 parent ac06d78 commit b7f041c

File tree

10 files changed

+451
-61
lines changed

10 files changed

+451
-61
lines changed

README.md

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ let params = {query: {completed: true}}
261261
store.dispatch('todos/find', params)
262262
```
263263

264+
See the section about pagination, below, for more information that is applicable to the `find` action.
265+
264266
#### `get(id)` or `get([id, params])`
265267
Query a single record from the server & add to Vuex store
266268
- `id {Number|String}` - the `id` of the record being requested from the API server.
@@ -318,6 +320,66 @@ Remove/delete the record with the given `id`.
318320
store.dispatch('todos/remove', 1)
319321
```
320322

323+
## Querying with Find & Pagination
324+
Both the `find` action and the `find` getter support pagination. There are differences in how they work.
325+
326+
### The `find` action
327+
328+
The `find` action queries data from the remote server. It returns a promise that resolves to the response from the server. The presence of pagination data will be determined by the server.
329+
330+
`[email protected]` can store pagination data on a per-query basis. The `pagination` store attribute maps queries to their most-recent pagination data. It's an empty object by default, but after performing a single query (with pagination in the response), it will have a `default` property. This property stores pagination information for the query. Here's what it will look like:
331+
332+
**`params = { query: {} }`**
333+
```js
334+
{
335+
pagination: {
336+
default: {
337+
query: {}, // Same as params.query
338+
ids: [0, 1, 2], // the ids in the store for the records that were returned from the server
339+
limit: 0, // the response.limit
340+
skip: 0, // the response.skip
341+
total: 3 // the response.total
342+
}
343+
}
344+
}
345+
```
346+
347+
It's possible that you'll want to store pagination information for more than one query. This might be for different components making queries against the same service, for example. You can use the `params.qid` (query identifier) property to assign a name to the query. If you set a `qid` of `mainListView`, for example, the pagination for this query will show up under `pagination.mainListView`. The `pagination.default` property will be used any time a `params.qid` is not provided. Here's an example of what this might look like:
348+
349+
**`params = { query: { $limit: 1 }, qid: 'mainListView' }`**
350+
```js
351+
// Data in the store
352+
{
353+
pagination: {
354+
mainListView: {
355+
query: { $limit: 1 }, // Same as params.query
356+
ids: [0], // the ids in the store for the records that were returned from the server
357+
limit: 1, // the response.limit
358+
skip: 0, // the response.skip
359+
total: 3 // the response.total
360+
}
361+
}
362+
}
363+
```
364+
365+
### The `find` getter
366+
367+
The `find` getter queries data from the local store using the same Feathers query syntax as on the server. It is synchronous and directly returns the results of the query. Pagination is **always** enabled and cannot be disabled. It accepts a params object with a `query` attribute. It does not use any other special attributes. The returned object looks just like a paginated result that you would receive from the server:
368+
369+
**`params = { query: {} }`**
370+
```js
371+
// The returned results object
372+
{
373+
data: [{ _id: 1, ...etc }, ...etc],
374+
limit: 0,
375+
skip: 0,
376+
total: 3
377+
}
378+
```
379+
380+
381+
###
382+
321383
## Customizing a Service's Default Store
322384

323385
As shown in the first example, the service module allows you to customize its store:
@@ -384,6 +446,6 @@ You can provide a `userService` in the auth plugin's options to automatically po
384446

385447
## License
386448

387-
Copyright (c) 2016
449+
Copyright (c) Forever and Ever, or at least the current year.
388450

389451
Licensed under the [MIT license](LICENSE).

src/service-module/actions.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
export default function makeServiceActions (service) {
22
const serviceActions = {
3-
find ({ commit, dispatch, getters }, params) {
3+
find ({ commit, dispatch, getters }, params = {}) {
44
commit('setFindPending')
5+
56
const handleResponse = response => {
7+
const { qid = 'default', query } = params
8+
69
dispatch('addOrUpdateList', response)
710
commit('unsetFindPending')
8-
return getters.find(params)
11+
12+
// The pagination data will be under `pagination.default` or whatever qid is passed.
13+
if (response.data) {
14+
commit('updatePaginationForQuery', { qid, response, query })
15+
}
16+
17+
return response
918
}
1019
const handleError = error => {
1120
commit('setFindError', Object.assign({}, error))

src/service-module/getters.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,11 @@ export default function makeServiceGetters (servicePath) {
2828
values = values.map(value => _.pick(value, ...filters.$select))
2929
}
3030

31-
const shouldPaginate = state.paginate && params.paginate !== false
32-
if (shouldPaginate) {
33-
return {
34-
total,
35-
limit: filters.$limit,
36-
skip: filters.$skip || 0,
37-
data: values
38-
}
39-
} else {
40-
return values
31+
return {
32+
total,
33+
limit: filters.$limit || 0,
34+
skip: filters.$skip || 0,
35+
data: values
4136
}
4237
},
4338
get: ({ keyedById, idField }) => (id, params = {}) => {

src/service-module/mutations.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,17 @@ export default function makeServiceMutations (servicePath) {
151151
_merge(current, state.copy)
152152
},
153153

154+
// Stores pagination data on state.pagination based on the query identifier (qid)
155+
// The qid must be manually assigned to `params.qid`
156+
updatePaginationForQuery (state, { qid, response, query }) {
157+
const { data, limit, skip, total } = response
158+
const { idField } = state
159+
const ids = data.map(item => {
160+
return item[idField]
161+
})
162+
state.pagination = { ...state.pagination, [qid]: { limit, skip, total, ids, query } }
163+
},
164+
154165
setFindPending (state) {
155166
state.isFindPending = true
156167
},

src/service-module/state.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default function makeDefaultState (servicePath, { idField, autoRemove, pa
77
idField,
88
servicePath,
99
autoRemove,
10-
paginate,
10+
pagination: {},
1111

1212
isFindPending: false,
1313
isGetPending: false,

test/index.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import './service-module/service-module.test.js'
22
import './service-module/misconfigured-client.test.js'
33
import './service-module/actions.test.js'
4+
import './service-module/getters.test.js'
45
import './service-module/mutations.test.js'
56
import './auth-module/auth-module.test.js'
67
import './auth-module/actions.test.js'

0 commit comments

Comments
 (0)