Simple Pagination for Angular 2 Applications

October 19, 2016
by Rahil Shaikh

It’s been a month since Google announced the release of the already popular framework Angular 2, since then it’s gaining more and more momentum as more developers and companies start moving towards Angular 2.

In this tutorial, we will learn to implement one of the basic features that any application requires while displaying a large number of list data. That is Angular 2 pagination. We will try to add pagination to our Angular 2 list with minimum complexity.

This is a pagination tutorial for Angular 2, if you are looking to add pagination to Angular 1 applications please visit here.

Angular 2 provides the ngFor directive to repeat through the list data and display it on the view just like we had the ng-repeat in AngularJS, you would know this if you are an Angular developer. This tutorial will help us paginate the list displayed using the ngFor directive for Angular 2 Applications.

DOWNLOAD

Head Start

To skip the cumbersome initial setup of Angular 2 application, I will clone a GitHub repo of a simple single page application we built using Angular 2 in one of our previous tutorials.

git clone https://github.com/rahil471/single-page-application-angular2.git angular2-pagination angular2-pagination

cd angular2-pagination

Next, let’s update the package.json to as below.

package.json

{
  "name": "angular2-pagination",
  "version": "1.0.0",
  "scripts": {
    "start": "tsc && concurrently "tsc -w" "lite-server" ",
    "lite": "lite-server",
    "postinstall": "typings install",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "typings": "typings"
  },
  "licenses": [
    {
      "type": "MIT",
      "url": "https://github.com/angular/angular.io/blob/master/LICENSE"
    }
  ],
  "dependencies": {
    "@angular/common": "~2.1.0",
    "@angular/compiler": "~2.1.0",
    "@angular/core": "~2.1.0",
    "@angular/forms": "~2.1.0",
    "@angular/http": "~2.1.0",
    "@angular/platform-browser": "~2.1.0",
    "@angular/platform-browser-dynamic": "~2.1.0",
    "@angular/router": "~3.1.0",
    "@angular/upgrade": "~2.1.0",
    "angular-in-memory-web-api": "~0.1.5",
    "bootstrap": "^3.3.7",
    "core-js": "^2.4.1",
    "reflect-metadata": "^0.1.8",
    "rxjs": "5.0.0-beta.12",
    "systemjs": "0.19.39",
    "zone.js": "^0.6.25"
  },
  "devDependencies": {
    "concurrently": "^3.0.0",
    "lite-server": "^2.2.2",
    "typescript": "^2.0.3",
    "typings": "^1.4.0"
  }
}

 

To install all the dependencies run

npm i

 

Once all the dependencies are installed, we can run the application using npm start. This should start up the application on our browser.

Angular 2 single page application

Angular 2 single page application

Display List using ngFor

To begin with, we first need to display a list of data using the ngFor directive provided by Angular 2. We have already covered on how to use ngFor directive to display list data in our previous tutorial, you can visit it here to learn in more detail.

Let’s just add it for this tutorial. We will display the list on our home page.

app/home/home.component.ts

import {Component} from [email protected]/core';

@Component({
    selector: 'app-home',
    template: `<h1>{{welcome}}</h1>
                <table class="table">
                    <tr>
                        <th>#</th>
                        <th>Game</th>
                        <th>Platform</th>
                        <th>Release</th>
                    </tr>
                    <tr *ngFor="let game of games; let i = index">
                        <td>{{i + 1}}</td>
                        <td>{{game.game}}</td>
                        <td>{{game.platform}}</td>
                        <td>{{game.release}}</td>
                    </tr>
                </table>`
})
export class HomeComponent {
    welcome : string;
    games : [{
        game: string,
        platform : string,
        release : string
    }];
    constructor(){
        this.welcome = "Display List using ngFor in Angular 2"

        this.games = [{
            game : "Deus Ex: Mankind Divided",
            platform: " Xbox One, PS4, PC",
            release : "August 23"
        },
        {
            game : "Hue",
            platform: " Xbox One, PS4, Vita, PC",
            release : "August 23"
        },
        {
            game : "The Huntsman: Winter's Curse",
            platform: "PS4",
            release : "August 23"
        },
        {
            game : "The Huntsman: Winter's Curse",
            platform: "PS4",
            release : "August 23"
        },
        {
            game : "Deus Ex: Mankind Divided",
            platform: " Xbox One, PS4, PC",
            release : "August 23"
        },
        {
            game : "Hue",
            platform: " Xbox One, PS4, Vita, PC",
            release : "August 23"
        },
        {
            game : "The Huntsman: Winter's Curse",
            platform: "PS4",
            release : "August 23"
        },
        {
            game : "The Huntsman: Winter's Curse",
            platform: "PS4",
            release : "August 23"
        },
        {
            game : "Deus Ex: Mankind Divided",
            platform: " Xbox One, PS4, PC",
            release : "August 23"
        },
        {
            game : "Hue",
            platform: " Xbox One, PS4, Vita, PC",
            release : "August 23"
        },
        {
            game : "The Huntsman: Winter's Curse",
            platform: "PS4",
            release : "August 23"
        },
        {
            game : "The Huntsman: Winter's Curse",
            platform: "PS4",
            release : "August 23"
        },
        {
            game : "Deus Ex: Mankind Divided",
            platform: " Xbox One, PS4, PC",
            release : "August 23"
        },
        {
            game : "Hue",
            platform: " Xbox One, PS4, Vita, PC",
            release : "August 23"
        },
        {
            game : "The Huntsman: Winter's Curse",
            platform: "PS4",
            release : "August 23"
        },
        {
            game : "The Huntsman: Winter's Curse",
            platform: "PS4",
            release : "August 23"
        },
        {
            game : "Deus Ex: Mankind Divided",
            platform: " Xbox One, PS4, PC",
            release : "August 23"
        },
        {
            game : "Hue",
            platform: " Xbox One, PS4, Vita, PC",
            release : "August 23"
        },
        {
            game : "The Huntsman: Winter's Curse",
            platform: "PS4",
            release : "August 23"
        },
        {
            game : "The Huntsman: Winter's Curse",
            platform: "PS4",
            release : "August 23"
        }]
    };
};

We have added a property games to our HomeComponent which is an array of objects, it holds a list of games. To increase the number of items for the demo, we are just repeating the objects.
In our template, we are displaying this list of games using the ngFor directive. Let’s just run the app and see what we have.

display list in Angular 2

list

If you see we are displaying 20 odd items in the list and it’s too long to be displayed at once. We need pagination!

Adding pagination in an Angular 2 list

There may be a number of ways and different modules available to implement pagination in Angular 2 Applications. But here we will learn arguably the simplest way possible to implement pagination in Angular 2. We wouldn’t need a single line of code in our component class related to pagination.

We will use the ng2-pagination module written by Michael Bromley. Let’s get started.

Installing the module

ng2-pagination is available as an npm package and we can very well install it using npm.

npm i ng2-pagination -S

This will install the ng2-pagination module and save it to package.json as a dependency.

Configuring our module loader

Once we have installed the module, we need to configure our module loader to look for ng2-pagination and load it in the browser. The configuration would depend on the module loader you are using. For this tutorial, we are using systemsjs. Here is the configuration for the same.

systemjs.config.js

/**
 * System configuration for Angular samples
 * Adjust as necessary for your application needs.
 */

(function (global) {
  System.config({
    paths: {
      // paths serve as alias
      'npm:': 'node_modules/'
    },
    // map tells the System loader where to look for things
    map: {
      // our app is within the app folder
      app: 'app',
      // angular bundles
      [email protected]/core': 'npm:@angular/core/bundles/core.umd.js',
      [email protected]/common': 'npm:@angular/common/bundles/common.umd.js',
      [email protected]/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
      [email protected]/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
      [email protected]/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
      [email protected]/http': 'npm:@angular/http/bundles/http.umd.js',
      [email protected]/router': 'npm:@angular/router/bundles/router.umd.js',
      [email protected]/forms': 'npm:@angular/forms/bundles/forms.umd.js',
      // other libraries
      'rxjs':                       'npm:rxjs',
      'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
      'ng2-pagination': 'npm:ng2-pagination' // add mapping for ng2-pagination
    },
    // packages tells the System loader how to load when no filename and/or no extension
    packages: {
      app: {
        main: './transpiled-js/main.js', //path to main.js
        defaultExtension: 'js'
      },
      rxjs: {
        defaultExtension: 'js'
      },
      'angular2-in-memory-web-api': {
        main: './index.js',
        defaultExtension: 'js'
      },
      'ng2-pagination': { //add configuration to load
        main: './index.js',
        defaultExtension: 'js'
      }
    }
  });
})(this);

Here we have added ng2-pagination into the map object and have also added the configuration for the same under packages.

Usage

Before we start using ng2-pagination, we need to import the module and declare it in our application module as a dependency, for this demo, we only have one module and that is the root module, so we will add it to the same. After doing so, your app.module.ts should look as shown below.

app.module.ts

import { NgModule }      from [email protected]/core';
import { BrowserModule } from [email protected]/platform-browser';
import {Ng2PaginationModule} from 'ng2-pagination'; //importing ng2-pagination

import { AppComponent }   from './app.component';
import { HomeComponent } from './home/home.component'; //import home components
import { AboutComponent } from './about/about.component'; //import about component
import { routing }  from './app.routing';

@NgModule({
  imports:      [ BrowserModule, routing, Ng2PaginationModule ], //other modules the app depends on
  declarations: [ AppComponent, AboutComponent, HomeComponent ], // declare all directives and components
  bootstrap : [ AppComponent ] // root component to bootstarp
})
export class AppModule { }

Once we have added the module as a dependency, it is ready to be used in our component.
ng2-pagination provides a pipe named paginate wich is used for paginating a list displayed via ngFor directive. Pipes in Angular 2 are a similar concept to filters in AngularJS. It also provides a pagination-controls component using which we can navigate through pages.
Once again open up home.component.ts and we will only change the template of our HomeComponent, the rest of it will remain the same.

app/home/home.component.ts

import {Component} from [email protected]/core';

@Component({
    selector: 'app-home',
    template: `<h1>{{welcome}}</h1>
                <table class="table">
                    <tr>
                        <th>#</th>
                        <th>Game</th>
                        <th>Platform</th>
                        <th>Release</th>
                    </tr>
                    <tr *ngFor="let game of games | paginate: {itemsPerPage: 5, currentPage:page, id: '1'}; let i = index">
                        <td>{{i + 1}}</td>
                        <td>{{game.game}}</td>
                        <td>{{game.platform}}</td>
                        <td>{{game.release}}</td>
                    </tr>
                </table>
                <pagination-controls (pageChange)="page = $event" id="1"
                      maxSize="5"
                      directionLinks="true"
                      autoHide="true">
                </pagination-controls>`
})
export class HomeComponent {
...
..
...
}

The paginate pipe takes in a few paramenters.

  • itemsPerPage – [number] (required) number of items to be displayed per page.
  • currentPage – [number] (required) current page number.
  • id – [string] A unique id to link the paginate pipe to the pagination-controls component, useful when you have multiple instances of pagination on one page.
  • totalItems – [number] Number of total items useful for server-side pagination, when you don not have all items at once.

To display the navigation links we use the pagination-control component provided by the ng2-pagination module, which takes in a few parameters.

  • pageChange – (event handles) triggers on page change, the $event argument holds the value of new page, should be used to update the value of the currentPage variable.
  • id – [string] A unique id to link the paginate pipe to the pagination-controls component, useful when you have multiple instances of pagination on one page.
  • maxSize – [string] Maximum number of page links to be displayed.

Run the application using npm start and you should have your pagination working.


 

I have added a bit of custom styling to the pagination-controls. You may style it the way you want.

There is more that we can do with ng2-pagination module, we can also implement server side pagination which we may cover in our future tutorials, we can also change the default template of the pagination-controls component visit it’s official GitHub page to look into it in detail.

Conclusion

Whether you are building smaller applications or a medium to large applications, if you want to list a considerable amount of data, the two options you have to display it neatly and conveniently are pagination and infinite scroll. In this Angular 2 Tutorial, we arguably learned the simplest way possible to add pagination to our Angular 2 application.

More Angular 2 Stuff

  1. Angular 2 Official Documentation
  2. Learn Angular 2 From our Free Video Course on YouTube
  3. Learn Angular 2 by building 12 apps
  4. Angular 2 by Istvan Novak

About

Engineer. Blogger. Thinker. Loves programming and working with emerging tech. We can also talk on Football, Gaming, World Politics, Monetary Systems.

Free PDF

Subscribe and get AngularJS Tips PDF. We never spam!
First Name:
Email:

14 comments

  1. Ayz Pat
    |

    How can we do the same using bootstrap only?

    • |

      Bootstrap is only for styling, at the most it can only change the look of your pagination links, but won’t give you any functionality.

  2. |

    Great post thanks for this..
    Question though; So if we have 2000 pages will you populate the bottom of the page with as many page numbers based on the quantity of pages ? I don’t think that will look good?

    • |

      There is a maxSize option for pagination-control that can be used to set the maximum number of page links to be displayed.

  3. dani
    |

    Thanks…but
    What if I dont want to show all the items in the array?

  4. |

    there is 1 issue , when i am at page 2 and select “about” tab and go back to “home” tab list is reloaded , cant we show where we left in pagination page

    • |

      That is how it is supposed to work. If you want to persist you page number then you’ll have to store the value of the page somewhere(localStorage could be one option) and set the currentPage when the component is viewed.

  5. Anthony Price (SevenSnake)
    |

    This was a great article. I had a problem when i search, and it only searched the table any object that was viewable. Adding the let i – index help me along with the pageChange. thanks.

    • Zahyda
      |

      Hello 🙂
      Put the paginate at the end of your all pipes.

      Examples :

  6. |

    Thanks for this. I have been having trouble with another library. But this was super simple and I was able to finish it quickly.

    • Rahil Shaikh
      |

      Great!

    • |

      Haha Sounds like you are coming from a Shark Tank Episode. 😀

  7. |

    Is there any way we can configure number of pages, I want to provide the number of pages from UI instead of hardcode in itemperpage

Leave a Comment