5

Does AngularJS have Limit and Offset request methods when calling an external data resource that supports them?

I imagine there is a more elegant solution than this, where I am passing the limit and offset via the routeParams:

function ListCtrl($scope, $http, $routeParams) {
$http.jsonp('http://www.example.com/api/list.jsonp?callback=JSON_CALLBACK&limit=' + $routeParams.limit + '&offset=' + $routeParams.offset,{callback: 'JSON_CALLBACK'}).success(function(data) {
$scope.list = data;
  });
}
sterling
  • 625
  • 2
  • 12
  • 23

3 Answers3

8

A complete pagination solution is: (1) a service that communicates with the server/database, (2) a directive to handle next/prev, and (3) a controller to glue it together.

Once you have the directive and the service, your controller is as simple as this:

app.controller('MainCtrl', function($scope, myData) {
  $scope.numPerPage = 5;
  $scope.noOfPages = Math.ceil(myData.count() / $scope.numPerPage);
  $scope.currentPage = 1;

  $scope.setPage = function () {
    $scope.data = myData.get( ($scope.currentPage - 1) * $scope.numPerPage, $scope.numPerPage );
  };

  $scope.$watch( 'currentPage', $scope.setPage );
});

With equally simple HTML:

<body ng-controller="MainCtrl">
  <ul>
    <li ng-repeat="item in data">{{item.name}}</li>
  </ul>
  <pagination num-pages="noOfPages" current-page="currentPage" class="pagination-small"></pagination>
</body>

Here's a complete Plunker: http://plnkr.co/edit/Mg0USx?p=preview. It uses the pagination directive of ui-bootstrap, which is a work in progress.

Josh David Miller
  • 120,525
  • 16
  • 127
  • 95
  • If the API returns smt like `{"data":[],"total":1000}` and you want to use the ui-boostrap pagination, then you have to use the `$promise` otherwise the `watch` function is fired twice (this is my understanding). i made this http://plnkr.co/edit/UFKtDXY8dWXEsczoankc and if you comment the code in `app.js` enabling the `get()` and disabling the `get().$promise` you will see how the function is called twice and the page will always be `1`. (the list does not change because it's faked, just look at the page number) – EsseTi Apr 26 '15 at 11:23
  • The `$promise` is a feature of [`$resource`](https://docs.angularjs.org/api/ngResource/service/$resource), which neither my answer nor the question assume is in use. – Josh David Miller Apr 28 '15 at 01:32
  • true, it's just that i run into this question why searching for a solution that used `$resource` .. – EsseTi Apr 28 '15 at 08:49
1

AngularJs is clientside. It is the external data resource's provider who should support those parameters.

A possible solution for your problem could be $resource (or the params option Mark mentioned):

var UserAccounts = $resource('/useraccounts/:userId/limit/:limit/offset:offset', {userId:'@id'});
var accounts = User.get({userId:123, limit:10, offset:10}, function() {
});

Of course, server side will need to read the parameters differently.

Community
  • 1
  • 1
asgoth
  • 35,552
  • 12
  • 89
  • 98
  • Thank you for the response. I will clarify my question so that it is clear that I am asking for the best way to have angular ask for limit / offset results. The resource provider does support them. – sterling Jan 05 '13 at 22:30
1

I'm not sure I understand your question, but $http methods have a config parameter which is an object, one property of which is the "params" object:

params – {Object.} – Map of strings or objects which will be turned to
?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified.

If your "limit" and "offset" values are in $routParams, then that seems like a fine place to get them from. However, you may want to consider wrapping the code that interfaces with your server into an Angular service. This service could store the current limit and offset values. You can inject the service into your controllers to get access to the functions (and/or data) that the service provides.

Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
  • Thank you for the info you've provided, that helped. To clarify I am trying to find the most elegant way to perform pagination on a large set of data coming from a remote resource. So when a user loads the page 10 results are shown and when they click next, 10 more are pulled from the resource server. – sterling Jan 06 '13 at 05:29
  • See if this helps: http://stackoverflow.com/questions/10816073/how-to-do-paging-in-angularjs – Mark Rajcok Jan 07 '13 at 15:36