Reputation: 1190
This is another follow up to a previous question. There are only two models involved: category
and game
which share a hasMany
relation. Example: The endpoint /Categories/1001/games/mature
list all games of fighting
category that have mature
flag set to true
. However, I am unable to paginate
the response. What is the proper way to paginate based on the code shown below? I would like to only display 10 results at a time.
common/models/category.js
Category.mature = function(id, callback) {
var app = this.app;
var Game = app.models.game;
Category.findById(id, {}, function(err, category) {
if (err) return callback(err);
//Now call the Game find method
Game.find({
"where": {
categoryId: id,
mature: true
}
}, function(err, gameArr) {
if (err) return callback(err);
callback(null, gameArr);
});
});
}
Category.remoteMethod(
'mature', {
accepts: [{
arg: 'id',
type: 'number',
required: true
}],
// mixing ':id' into the rest url allows $owner to be determined and used for access control
http: {
path: '/:id/games/mature',
verb: 'get'
},
returns: {
arg: 'games',
type: 'array'
}
}
);
Tables/Models
catgories
category_name category_id
------------- -----------
fighting 1001
racing 1002
sports 1003
games
game_id game_name category_id mature description published_date
----------- ------------ ----------- ------- ----------- --------------
13KXZ74XL8M Tekken 10001 true Published by Namco. 1994
138XZ5LPJgM Forza 10002 false Published by Microsoft 2005
API Result:
games [
{
gameName: 'Tekken',
gameInfo :
[
{
description : 'Published by Namco.',
published_date : '1994'
}
],
categorName: 'fighting',
categoryId: 1001,
mature: true
}
.....
]
Upvotes: 0
Views: 371
Reputation: 3396
If you are stuck with the code above, you will need to download the full set of Games and then paginate on the frontend. Without being able to send in limit
and skip
values to your queries, there is no other way.
If you can change this code and add arguments to the remote method, the underlying mysql connector format with the Node API would look like this:
Game.find({
"where": {
categoryId: id,
mature: true
},
"limit": 10, // 10 per page
"skip": 10 // hard coded for page 2, this needs to be passed in
}, function(err, gameArr) {
if (err) return callback(err);
callback(null, gameArr);
});
The values for limit and skip should be added to your remote method definition and registration, and then the UI can send in dynamic values based on the page displayed.
The page on the skip filter has an example for pagination as well:
https://docs.strongloop.com/display/public/LB/Skip+filter
If this will be using some sort of UI library like the Angular SDK, you can make the same query at the Controller level using the lb-ng generator script and the models created there. You could also add the pagination values there, no need for a custom remote method.
Update:
To add the skip and limit numbers to your remote method, you need to update your remote method signature, the accepts
array would change to
accepts: [
{
arg: 'id',
type: 'number',
required: true
},
{
arg: 'skip',
type: 'number',
required: true
},
{
arg: 'limit',
type: 'number',
required: true
}
]
And then add the same 2 new arguments to the method itself:
Category.mature = function(id, skip, limit, callback) {
// ...your code...
});
You can call it using query parameters at this point, like ?skip=10&limit=10
just appended to the existing path. Or, you can change the http.path
to something like
path: '/:id/games/mature/:skip/:limit'
and then call the resource with /1/games/mature/10/10
to achieve the same result with a parameterized URL.
Upvotes: 2