Skip to content

Commit

Permalink
Test coverage, allow customization of metadata parsing params, docume…
Browse files Browse the repository at this point in the history
…ntation
  • Loading branch information
Mike North committed May 20, 2015
1 parent c37a5fe commit 6e82daf
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 10 deletions.
63 changes: 56 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,67 @@ Now, whenever the `infinity-loader` is in view, it will send an action to the ro

When the new records are loaded, they will automatically be pushed into the Model array.

#### JSON Response
## Advanced Usage

### JSON Request/Response Customization

By default, ember-infinity will send pagination parameters as part of a GET request as follows

````
/items?per_page=5&page=1
````

The response provided by your server should include the number of total pages.
and will expect to recieve metadata in the response payload via a `total_pages` param in a `meta` object

```json
{ "meta": { "total_pages": 4 } }
```js
{
items: [
{id: 1, name: 'Test'},
{id: 2, name: 'Test 2'}
],
meta: {
total_pages: 3
}
}
```

If your query returns 20 objects, and you're showing 6 per page, then the
number of total pages would be 4.
If you wish to customize some aspects of the JSON contract for pagination, you may do so via your routes. For example:

## Advanced Usage
```js
import Ember from 'ember';
import InfinityRoute from "ember-infinity/mixins/route";

export default Ember.Route.extend(InfinityRoute, {

perPageParam: "per", // instead of "per_page"
pageParam: "pg", // instead of "page"
totalPagesParam: "meta.total", // instead of "meta.total_pages"

model() {
/* Load pages of the Product Model, starting from page 1, in groups of 12. */
return this.infinityModel("product", { perPage: 12, startingPage: 1 });
}
});
```

This will result in request query params being sent out as follows

````
/items?per=5&pg=1
````

and ember-infinity will be set up to parse the total number of pages from a JSON response like this:

```js
{
items: [
...
],
meta: {
total: 3
}
}
```

### infinityModel

Expand Down
14 changes: 11 additions & 3 deletions addon/mixins/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ export default Ember.Mixin.create({
*/
pageParam: 'page',

/**
* Path of the "total pages" param in
* the HTTP response
* @type {String}
* @default "meta.total_pages"
*/
totalPagesParam: 'meta.total_pages',

/**
@private
@property _canLoadMore
Expand Down Expand Up @@ -137,14 +145,14 @@ export default Ember.Mixin.create({
var promise = this.store.find(modelName, params);

promise.then(
function(infinityModel) {
var totalPages = infinityModel.get('meta.total_pages');
infinityModel => {
var totalPages = infinityModel.get(this.get('totalPagesParam'));
_this.set('_currentPage', startingPage);
_this.set('_totalPages', totalPages);
infinityModel.set('reachedInfinity', !_this.get('_canLoadMore'));
Ember.run.scheduleOnce('afterRender', _this, 'infinityModelUpdated', { lastPageLoaded: startingPage, totalPages: totalPages, newObjects: infinityModel });
},
function() {
() => {
throw new Ember.Error("Could not fetch Infinity Model. Please check your serverside configuration.");
}
);
Expand Down
65 changes: 65 additions & 0 deletions tests/unit/mixins/route-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,71 @@ test('it sets state before it reaches the end', function(assert) {
assert.ok(!model.get('reachedInfinity'), 'Should not reach infinity');
});

test('it allows customizations of request params', assert => {
var RouteObject = Ember.Route.extend(RouteMixin, {
perPageParam: 'per',
pageParam: 'p',
model() {
return this.infinityModel('item');
}
});
var route = RouteObject.create();

var dummyStore = {
find(modelType, findQuery) {
assert.deepEqual(findQuery, {per: 25, p: 1});
return new Ember.RSVP.Promise(resolve => {
Ember.run(this, resolve, Ember.Object.create({
items: []
}));
});
}
};

route.store = dummyStore;

var model;
Ember.run(function() {
route.model().then(function(result) {
model = result;
});
});
});

test('it allows customizations of meta parsing params', assert => {
var RouteObject = Ember.Route.extend(RouteMixin, {
totalPagesParam: 'pagination.total',
model() {
return this.infinityModel('item');
}
});
var route = RouteObject.create();

var dummyStore = {
find(modelType, findQuery) {
return new Ember.RSVP.Promise(resolve => {
Ember.run(this, resolve, Ember.Object.create({
items: [{id: 1, name: 'Walter White'}],
pagination: {
total: 22
}
}));
});
}
};

route.store = dummyStore;

var model;
Ember.run(function() {
route.model().then(function(result) {
model = result;
});
});

assert.equal(22, route.get('_totalPages'));
});

test('it sets state when it reaches the end', function(assert) {

var RouteObject = Ember.Route.extend(RouteMixin, {
Expand Down

0 comments on commit 6e82daf

Please sign in to comment.