This tutorial will show us how to implement Server Side Pagination in our AngularJS applications. In any application when dealing with a list or tabular data, you would probably need pagination.

We have already seen in one of our previous articles how we can implement client side pagination in AngularJs with ease. Although server-side pagination sounds to be difficult but it won’t after you follow this article.

Concept

When working with asynchronous pagination, we fetch only one page of data at a time from the server. So if the user has clicked on page two we will fetch the result set only for page 2.

DEMO  DOWNLOAD

Overview

At the client side again we will be using dir-paginate like we did for client-side pagination. The API that returns us the data will take two parameters, the page number and items per page. So for example, if you are on your 2nd page and the items displayed per page is 10 the api should return 10 items starting from 11th position. Along with the data, the API will also return the count of total data. The total count is crucial for creating the pagination links. An alternative way is to pass the offset (Position of the result from which the data should be returned) instead of the page number.
 

Pagination API explanation

The API or method used to return the paginated data would require 2 parameters for our demo. The page number for which the data is requested and the number of items per page.
The API structure would be some thing like this.

http://yourdomain/apiname/{itemsPerPage}/{pagenumber}

Depending on the values of the itemsPerPage and pagenumber you will make appropriate request to your database. For example.
If your {itemsPerPage} is 10 and {pagenumber} is 3. Your API would look like this.
http://yourdomain/apiname/10/3.
And your corresponding MySQL query would be.
SELECT * FROM 'table_name' LIMIT ({pagenumber}-1)*{itemsPerPage},{itemsPerPage}
That results in.
SELECT * FROM 'table_name' LIMIT 20,10
This would return you rows from 21 to 30 (MySQL starts from 0) that would be your 3rd page. And if you are using offset as a parameter instead of pagenumber, you can simply do LIMIT {offset}-1,{itemsPerPage}, again -1 because the 1st row is the 0th position in MySQL.

Implementation

First we need to grab the required files and set up our HTML. We need dirPagination.js for our pagination. If you are using bower, you can download the files by running.

bower install angular-utils-pagination

Alternatively you can download it from the below link.

dirPagination.js

index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Server Pagination in Angular js</title>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css">
    <link rel="stylesheet" type="text/css" href="css/styles.css">
  </head>
  <body>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.1/angular.js"></script>
        <script src="lib/dirPagination.js"></script>
        <script src="app/app.js"></script>
  </body>
</html>
app/app.js
var app = angular.module('angularTable', ['angularUtils.directives.dirPagination']);
app.controller('listdata',function($http){
    var vm = this;
    vm.users = []; //declare an empty array
    vm.pageno = 1; // initialize page no to 1
    vm.total_count = 0;
    vm.itemsPerPage = 10; //this could be a dynamic value from a drop down
    vm.getData = function(pageno){ // This would fetch the data on page change.
        //In practice this should be in a factory.
        vm.users = [];  $http.get("http://yourdomain/apiname/{itemsPerPage}/{pagenumber}").success(function(response){
            //ajax request to fetch data into vm.data
                       vm.users = response.data;  // data to be displayed on current page.
            vm.total_count = response.total_count; // total data count.
        });
    };
    vm.getData(vm.pageno); // Call the function to fetch initial data on page load.
});
  1. vm.users – Will hold the set of data to be displayed on the page.
  2. vm.pageno – Sets the page to 1 on load.
  3. vm.total_count – Stores the total no. of results, this value will be returned by the API
  4. vm.itemsPerPage – Number of items to be displayed per page. (Can be made dynamic )
  5. vm.getData() – Is a function that will fetch us the result every-time the user clicks on a new page. We also call this function once on load to fetch the data for page 1

 
Now that we have our controller setup lets complete our markup.
So to repeat on the data set, we will use the dir-paginate directive instead of ng-repeat. We will also assign the total_count to the total-items directive provided by dirPagination. Remember dir-paginate will use this number as reference to setup your pagination links.

<tr dir-paginate=”user in data.users|itemsPerPage:data.itemsPerPage” total-items=”data.total_count”>

 
Next we will add the pagination links using the dir-pagination-controls directive, which is also provided by dirPagination.

Pagination controls
    <dir-pagination-controls
        max-size="8"
        direction-links="true"
        boundary-links="true"
        on-page-change="data.getData(newPageNumber)">
    </dir-pagination-controls>

The on-page-change directive is the key here, it takes in a callback function which is triggered on every page change. We will use this to call our vm.getdata(pageno) function. This will again make a request to the server with the new page number and our API will return the data for the next page.

Don’t forget to declare your ng-app and ng-controller ;). Take a look at our complete markup.

index.html
<!doctype html>
<html lang="en" ng-app="angularTable">
  <head>
    <meta charset="utf-8">
    <title>Server Side Pagination in Angular js</title>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css">
    <link rel="stylesheet" type="text/css" href="css/styles.css">
  </head>
  <body>
    <div role="main" class="container theme-showcase">
      <div class="" style="margin-top:90px;">
        <div class="col-lg-8">
            <div class="page-header">
                <h2 id="tables">Server Side pagination in Angular js</h2>
            </div>
            <div class="bs-component" ng-controller="listdata as data">
                <table class="table table-striped table-hover">
                    <thead>
                        <tr>
                            <th>Id</th>
                            <th>First Name</th>
                            <th>Last Name</th>
                            <th>Full Name</th>
                            <th>Email</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr ng-show="data.users.length <= 0"><td colspan="5" style="text-align:center;">Loading new data!!</td></tr>
                        <tr dir-paginate="user in data.users|itemsPerPage:data.itemsPerPage" total-items="data.total_count">
                            <td>{{user.index}}</td>
                            <td>{{user.name}}</td>
                            <td>{{user.surname}}</td>
                            <td>{{user.fullname}}</td>
                            <td>{{user.email}}</td>
                        </tr>
                    </tbody>
                </table>
                <dir-pagination-controls
                   max-size="8"
                   direction-links="true"
                   boundary-links="true"
                   on-page-change="data.getData(newPageNumber)" >
                </dir-pagination-controls>
            </div>
        </div>
      </div>
    </div>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.1/angular.js"></script>
        <script src="lib/dirPagination.js"></script>
        <script src="app/app.js"></script>
  </body>
</html>

ng-controller="listdata as data" is from the ControllerAs syntax. This was it for this application, you can explore more and check out more options provided by dirPaginate here.
 

Conclusion

In this article, we saw how we can easily implement Server Side Pagination in Angular Applications. This type of pagination is usually required when you have a large data set. It reduces loading time and also makes your DOM much lighter.

56 Comments

    1. Hi Mahesh,
      Api which you are trying to access is not allowed from origin. that’s why you getting that error.
      Either you have to make another one or else you can use some dummy json data.
      Thanks.

      1. Do you have a simple example code for filter?
        I am developing an e-commerce site, basically a product grid where you can filter and paginate. For example filter buttons like:
        Big ones
        Small ones

        Example url: “http://my-site.com/products.json?size=small

        (Great article, many thanks in advance)

          1. Many thanks , but I was asking for a server-side mode to filter, sort and paginate by JSON. I have been implementing your “server-side pagination” and it works fine!, but I am not expert to add filters and sort mode.

  1. I am sure that my service is returning the valu e in JSON format and it worked with the client side scripting too.

    But here , how can i make sure vm.users has the value .
    My chrome do even show any error , post excution of the query i am getting blank page .

    why there is no post method to send the pageno record no ?
    ————————————————for ORGIn Error

    Access-Control-Allow-Origin * at Server header

  2. Ok !! sorry !! your code is so perfect ..!!

    I am so noob !! .. I was using web service and data was not as the api data format.

    i got the o/p .
    thanks and a lot for beautiful tutorial ..!!

    You so smart !!! so quickly and nicely done !!

    Keep it up and keep sharing !!
    sharing is caring !! TC!!

  3. Dear Rahil Sheikh, can you please share server side code of MySQL API,
    it’s not working on localhost, i could not get values from path,

  4. So i’ve been looking at various versions of builds using the dirPagination.js file and i’m noticing something….

    the pagination functions of getCurrentPage and setCurrentPage fire multiple times on page load, and on page change and it makes no difference if it’s a client Side paging, or server side Paging, or XHR paging….

    it fires multiple times…

    this script needs to be seriously refactored because it is really uncool to watch page flashing because it’s loading multiple times…

    1. This should not happen, if you are using multiple pagination on same page make sure you are providing a pagination-id.
      Try tweaking the demo code and test.
      If you are facing this issue without any solution, email me the src code if possible, I’ll look into it.

  5. How are you 🙂
    I’ve been using this more or less and it was working properly however I want this to be dynamic. So I’m compiling the HTML rather than using partials and injecting the compiled html into the page.

    Every page is using the same tableService to create the table, so I need to be able to access the dirPagination.js script functions directly. I’ve managed everything except dealing with the controller. It’s connected but nothing works.

    The only other option I have is to treat this as deprecated and force a page reload each time the itemsPerPage is changed and the page is changed, which is rather silly within an angular application.

    Loading the entire collection was the way I initially started it but with the collections ranging from 10,000 to 1,000,000 this isn’t efficient.

    I think that this script is useful for simple things but not really for enterprise ERP systems.

    Any help would be appreciated.

  6. im showing 10 records per page and it showing as well but the pagination controls are not showing.

  7. hai rahil….

    i have a problem,i have 10 records in responce variable and i am trying to display 5 records for each page by using pagination and giving index position to each record,when i was click to go next page in pagination the index position for 6th record is displaying as 1st record insted of 6th number….i need it’s display as 6th and 7th continuously….please give me a solution.

  8. Hi sir,
    It is good work. I tried with this example and try to change the number of items per page by using text box. It loads properly but there is one small issue the page number not get updated. for example initially i said the page number 10 and navigate to 2nd page and change the page size is 5 then it should move to 1st page. Can you please help on it.

  9. Hello dude, was sucessfull this pagination in my web application, but the menu class “pagination” was not applicated, i would like to know what i missed or what can i do for my web app have a menu or if i can have a contact from someone that can help me i would be grateful!

  10. Hi there,
    First of all thanks about your article, but the demo seems not working !!!
    could you please check it out.
    thanks
    Best regards

  11. Hi rahil i am using this in angularjs. So i am getting 200 objects but pagination is not showing may i know any thing problem.

Leave a Reply

Your email address will not be published. Required fields are marked *