How to implement on scrolldown pagination in Angular 4

Swapnil Yeole picture Swapnil Yeole · Nov 16, 2017 · Viewed 25.7k times · Source

I am new in angular 4. I want to implement scroll pagination in angular 4. Initially I want to show 20 records. After scroll down I want to show next 20. I will do the same till end of list.

I tried to implement it using "angular2-infinite-scroll". but I am not able to show initially first 20 records as well scroll data.

component file :

 import { Component, OnInit } from '@angular/core';
 import { InfiniteScrollModule } from 'angular2-infinite-scroll';

    @Component({
      selector: 'app-scroll',
      templateUrl: `./scroll.component.html`,
      styleUrls: ['./scroll.component.css']
    })
    export class ScrollComponent implements OnInit {

    let item = [{
        "Name": "XYz Compnay"
    },
    {
        "Name": "XYz Company1"
    }, {
        "Name": "XYz Company2"
    }, {
        "Name": "XYz Company3"
    }, {
        "Name": "XYz Company4"
    }, {
        "Name": "XYz Company5"
    }];
      constructor() {}
      ngOnInit() {}

      onScroll () {
        alert('scrolled!!');    
      }

     }

HTML file :

<div
         infinite-scroll
         [infiniteScrollDistance]="2"
         [infiniteScrollThrottle]="10"
         (scrolled)="onScroll()"
         >
      <p *ngFor="let items of item">
        {{items.Name}}
      </p>
    </div>  

If anyone having about it please share same.

Answer

Dhyey picture Dhyey · Nov 16, 2017

I recommend using ngx-infinite-scroll against angular2-infinite-scroll due to new features and compatibility with AOT.

First you need to specify the scrollWindow property if you are not using the whole window and using overflow: scroll property to emulate a scrollable div. Also in your ScrollComponent class you need to have item as a property of class and not a variable, so you should use public item instead of let item.

If the size of list is already known than you can leverage infiniteScrollDisabled to improve performance.

Also as it is grammatically incorrect to name multiple things as item and call single thing an item. I am going to change item to items ( You can see that in the ngFor loop in template html )

@Component({
    selector: 'my-app',
    styles: [`
    .search-results {
        height: 100px;
        overflow: scroll;
    }
    `],
    template: `
    <div class="search-results"
    infiniteScroll
    [infiniteScrollDistance]="2"
    [infiniteScrollThrottle]="50"
    (scrolled)="onScroll()"
    [infiniteScrollDisabled]="isFullListDisplayed"
    [scrollWindow]="false">
        <p *ngFor="let item of itemsToShow; let i = index">
        {{i + ' ' + item.Name}}
        </p>
    </div>
    `
})
export class AppComponent {
    private noOfItemsToShowInitially: number = 5;
    // itemsToLoad - number of new items to be displayed
    private itemsToLoad: number = 5;
    // 18 items loaded for demo purposes
    private items = [
        {
            "Name": "XYz Company0"
        },
        {
            "Name": "XYz Company1"
        },
        {
            "Name": "XYz Company2"
        },
        {
            "Name": "XYz Company3"
        },
        {
            "Name": "XYz Company4"
        },
        {
            "Name": "XYz Company5"
        },
        {
            "Name": "XYz Company6"
        },
        {
            "Name": "XYz Company7"
        },
        {
            "Name": "XYz Company8"
        },
        {
            "Name": "XYz Company9"
        },
        {
            "Name": "XYz Company10"
        },
        {
            "Name": "XYz Company11"
        },
        {
            "Name": "XYz Company12"
        },
        {
            "Name": "XYz Company13"
        },
        {
            "Name": "XYz Company14"
        },
        {
            "Name": "XYz Company15"
        },
        {
            "Name": "XYz Company16"
        },
        {
            "Name": "XYz Company17"
        }
    ];
    // List that is going to be actually displayed to user
    public itemsToShow = this.items.slice(0, this.noOfItemsToShowInitially);
    // No need to call onScroll if full list has already been displayed
    public isFullListDisplayed: boolean = false;

    onScroll() {
        if (this.noOfItemsToShowInitially <= this.items.length) {
            // Update ending position to select more items from the array
            this.noOfItemsToShowInitially += this.itemsToLoad;
            this.itemsToShow = this.items.slice(0, this.noOfItemsToShowInitially);
            console.log("scrolled");
        } else {
            this.isFullListDisplayed = true;
        }
    }
}

You will now successfully see an alert message when you scroll down the list.

Here is a working plunker of above code.