×

iFour Logo

Implementation of Ngx Infinite Scroller using Angular Application

Kapil Panchal - February 11, 2021

Listening is fun too.

Straighten your back and cherish with coffee - PLAY !

  • play
  • pause
  • pause
Implementation of Ngx Infinite Scroller using Angular Application

In this blog, we will introduce infinite scrolling in our Angular application. When we prepare an application, we deal with tons of files at the same time. In this situation, a question will be asked: how to display thousands of registrations on a single page?

It is not a good practice to load thousands of records at once on one page, and there are many benefits to implement infinite scrolling.

  • Increase the time on our web site so that we can have faster operations

  • Make it easy to increase the depth of the page

  • The minimum number of clicks required

  • Better user interface

  • Best in mobile layout

  • One of the major advantages is that it reduces the bounce rate of a website

To implement infinite scrolling in Angular, we can use an npm package named ngx-infinite-scroll.

To begin with infinite scrolling, we just need to create a new project by following some steps that are described below.

Create a new angular project according as per the following command:

ng new ngxInfiniteScrollerDemo                  
                

We have created two components in our project using the following commands:

ng generate component hello

ng generate component scrollContainer
                

Above is the basic step required to create a project with its required components, moreover, we need to install another npm package known as ngx-infinite-scroll, to work with infinite scrolling in our app, to do this we just need to use the below-mentioned npm:

npm install ngx-infinite-scroll
                

Besides the above dependencies, we used angular material to design our page, so we installed angular/cdk.

npm install @angular/cdk
                

To implement the infinite scroll, we will first design our user interface, so our app.component.html and app.component.css code snippet are the following:

App.component.html

                  

            
            
            
        {{ column | titlecase }}
      
            {{ item[column] }}
    
            
            
  

                  
App.component.css
:host {
  justify-content: flex-start;
  display: flex;
  flex-direction: column;
}

app-scroll-container {
  flex-grow: 0;
  flex-shrink: 0;
}

app-scroll-container.full {
  flex-basis: auto;
}

app-scroll-container.part {
  flex-basis: 200px;
}

.buttons {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 1000;
}

We have created multiple arrays named with ELEMENT_DATA in which we have stored data like serial_no, name, weight, and height. Then we have used mat table to display the data through the getData() method like the following code:

App.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import { Sort, MatSort, MatTableDataSource } from '@angular/material';
import { noop as _noop } from 'lodash-es';

interface Element {
  name: string;
  serial_no: number;
  weight: number;
  height: number;
}

const ELEMENT_DATA: Element[] = [
  {serial_no: 1, name: 'Bunty', weight: 50, height: 5.1},
  {serial_no: 2, name: 'Gaurav', weight: 52, height: 5.2},
  {serial_no: 3, name: 'Jayraj', weight: 69, height: 5.5},
  {serial_no: 4, name: 'Lokesh', weight: 90, height: 6},
  {serial_no: 5, name: 'Hardik', weight: 41, height: 5},
  {serial_no: 6, name: 'Sunil', weight: 27, height: 6},
  {serial_no: 7, name: 'Aniket', weight: 45, height: 4.5},
  {serial_no: 8, name: 'Jignesh', weight: 94, height: 6},
  {serial_no: 9, name: 'Abdul', weight: 84, height: 5},
  {serial_no: 10, name: 'James', weight: 29, height: 4},
  {serial_no: 11, name: 'Jigar', weight: 56, height: 5.1},
  {serial_no: 12, name: 'Jaimin', weight: 35, height: 5},
  {serial_no: 13, name: 'Nitin', weight: 68, height: 5.5},
  {serial_no: 14, name: 'Suhani', weight: 85, height: 3.5},
  {serial_no: 16, name: 'Lalit', weight: 36, height: 4},
  {serial_no: 17, name: 'Hiren', weight: 53, height: 4.5},
  {serial_no: 18, name: 'Himanshu', weight: 48, height: 4},
  {serial_no: 19, name: 'Piyush', weight: 93, height: 5},
  {serial_no: 20, name: 'Keval', weight: 78, height: 5.2},
];

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

  dataSource: MatTableDataSource;
  limit: number = 1000;
  displayedColumns: string[] = ['serial_no', 'name', 'weight', 'height'];
  full: boolean = true;
  @ViewChild(MatSort) sort: MatSort;
  
  constructor() { }

  ngOnInit() {
    this.getData();
  }

  handleScroll = (scrolled: boolean) => {
    console.timeEnd('lastScrolled');
    scrolled ? this.getData() : _noop();
    console.time('lastScrolled');
  }
  hasMore = () => !this.dataSource || this.dataSource.data.length < this.limit;

  getData() {
    const data: Element[] = this.dataSource
      ? [...this.dataSource.data, ...ELEMENT_DATA]
      : ELEMENT_DATA;
    this.dataSource = new MatTableDataSource(data);
    this.dataSource.sort = this.sort;
  }
}
  

In our scroll-component we have created the methods to implement infinite scrolling, in these, we have provided some properties to an item to function with scrolling like the following:

  • infiniteScroll is the primary property that defines the content that is scrolling through.

  • infiniteScrollDistance is Used to provide the distance where we will reach the defined percentage of the item, at which time the scrolling event will be triggered.

  • infinteScrollThrottle indicates the number of milliseconds after the scrolling event will be triggered.

  • Scrolled is a method for carrying out a specific action when scrolling is reached.

  • In scrollWindow, we should decide if we want to listen to the window scroll or scroll event.

So, these are some of the properties we used in this demonstration project, but we can use more methods or properties depending on our requirements.

So, our code main to implement infinite scrolling is in our scroll-container like the following:

Scroll-container.component.ts
import { Component, OnInit, OnChanges, Input, Output, EventEmitter, HostListener, ElementRef } from '@angular/core';
import { throttle as _throttle, noop as _noop } from "lodash-es";

enum ScrollDirection {
  UP = 'up',
  DOWN = 'down'
}

enum ScrollListener {
  HOST = 'scroll',
  WINDOW = 'window:scroll'
}

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

  private _element: Element;
  private _window: Element;
  public scrollTop = 0;
  @Input() more = true;
  @Input() scrollDelay = 500;
  @Input() scrollOffset = 1000;
  @Output() scrolled: EventEmitter = new EventEmitter();
  @HostListener(ScrollListener.HOST) _scroll: Function;
  @HostListener(ScrollListener.WINDOW) _windowScroll: Function;

  constructor(private elRef: ElementRef) {
    this._element = this.elRef.nativeElement;
    this._window = document.documentElement as Element;
  }

  ngOnInit() {
    this.setThrottle();
  }

  ngOnChanges(changes) {
    if (changes.scrollDelay) this.setThrottle();
  }

  setThrottle() {
    this._scroll = this._windowScroll = _throttle(this.handleScroll, this.scrollDelay);
  }

  getListener = () => this.elRef.nativeElement.clientHeight === this.elRef.nativeElement.scrollHeight
    ? ScrollListener.WINDOW
: ScrollListener.HOST

  roundTo = (from: number, to: number = this.scrollOffset) => Math.floor(from / to) * to;
  getScrollDirection = (st: number) => this.scrollTop <= st ? ScrollDirection.DOWN : ScrollDirection.UP;

  canScroll(e: Element): boolean {
    const scrolled = this.more
      && this.getScrollDirection(e.scrollTop) === ScrollDirection.DOWN
      && this.roundTo(e.clientHeight) === this.roundTo(e.scrollHeight - e.scrollTop);
    this.scrollTop = e.scrollTop;
    return scrolled;
  }

  handleScroll = () => this.getListener() === ScrollListener.HOST
    ? this.scrolled.emit( this.canScroll(this._element) )
    : this.scrolled.emit( this.canScroll(this._window) )
}
 
Scroll-container.component.html

Looking for Trusted Angular Development Company? Enquire Today.

Our app.module.ts file looks like the following

App.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatTableModule, MatSortModule, MatProgressSpinnerModule } from '@angular/material';

import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
import { ScrollContainerComponent } from './scroll-container/scroll-container.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule, BrowserAnimationsModule, MatTableModule, MatSortModule, MatProgressSpinnerModule ],
  declarations: [ AppComponent, HelloComponent, ScrollContainerComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

Output

When we execute our project, we can see the output on the following screen.

Azure vs AWS

 

Figure 1: Output screen of our infinite scroller demo

 

Azure vs AWS

Figure 2: Output screen after scrolling

Conclusion


In this blog, we have discussed ngx infinite scrolling, discussed its properties and methods for implementing it. We have also implemented the demonstration project for a better understanding of it.

Implementation of Ngx Infinite Scroller using Angular Application In this blog, we will introduce infinite scrolling in our Angular application. When we prepare an application, we deal with tons of files at the same time. In this situation, a question will be asked: how to display thousands of registrations on a single page? It is not a good practice to load thousands of records at once on one page, and there are many benefits to implement infinite scrolling. Increase the time on our web site so that we can have faster operations Make it easy to increase the depth of the page The minimum number of clicks required Better user interface Best in mobile layout One of the major advantages is that it reduces the bounce rate of a website To implement infinite scrolling in Angular, we can use an npm package named ngx-infinite-scroll. To begin with infinite scrolling, we just need to create a new project by following some steps that are described below. Create a new angular project according as per the following command: ng new ngxInfiniteScrollerDemo We have created two components in our project using the following commands: ng generate component hello ng generate component scrollContainer Above is the basic step required to create a project with its required components, moreover, we need to install another npm package known as ngx-infinite-scroll, to work with infinite scrolling in our app, to do this we just need to use the below-mentioned npm: npm install ngx-infinite-scroll Besides the above dependencies, we used angular material to design our page, so we installed angular/cdk. npm install @angular/cdk To implement the infinite scroll, we will first design our user interface, so our app.component.html and app.component.css code snippet are the following: App.component.html {{ column | titlecase }} {{ item[column] }} App.component.css :host { justify-content: flex-start; display: flex; flex-direction: column; } app-scroll-container { flex-grow: 0; flex-shrink: 0; } app-scroll-container.full { flex-basis: auto; } app-scroll-container.part { flex-basis: 200px; } .buttons { position: absolute; top: 0; right: 0; z-index: 1000; } Read More: Error Handling Using Angular Rxjs We have created multiple arrays named with ELEMENT_DATA in which we have stored data like serial_no, name, weight, and height. Then we have used mat table to display the data through the getData() method like the following code: App.component.ts import { Component, OnInit, ViewChild } from '@angular/core'; import { Sort, MatSort, MatTableDataSource } from '@angular/material'; import { noop as _noop } from 'lodash-es'; interface Element { name: string; serial_no: number; weight: number; height: number; } const ELEMENT_DATA: Element[] = [ {serial_no: 1, name: 'Bunty', weight: 50, height: 5.1}, {serial_no: 2, name: 'Gaurav', weight: 52, height: 5.2}, {serial_no: 3, name: 'Jayraj', weight: 69, height: 5.5}, {serial_no: 4, name: 'Lokesh', weight: 90, height: 6}, {serial_no: 5, name: 'Hardik', weight: 41, height: 5}, {serial_no: 6, name: 'Sunil', weight: 27, height: 6}, {serial_no: 7, name: 'Aniket', weight: 45, height: 4.5}, {serial_no: 8, name: 'Jignesh', weight: 94, height: 6}, {serial_no: 9, name: 'Abdul', weight: 84, height: 5}, {serial_no: 10, name: 'James', weight: 29, height: 4}, {serial_no: 11, name: 'Jigar', weight: 56, height: 5.1}, {serial_no: 12, name: 'Jaimin', weight: 35, height: 5}, {serial_no: 13, name: 'Nitin', weight: 68, height: 5.5}, {serial_no: 14, name: 'Suhani', weight: 85, height: 3.5}, {serial_no: 16, name: 'Lalit', weight: 36, height: 4}, {serial_no: 17, name: 'Hiren', weight: 53, height: 4.5}, {serial_no: 18, name: 'Himanshu', weight: 48, height: 4}, {serial_no: 19, name: 'Piyush', weight: 93, height: 5}, {serial_no: 20, name: 'Keval', weight: 78, height: 5.2}, ]; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: [ './app.component.css' ] }) export class AppComponent implements OnInit { dataSource: MatTableDataSource; limit: number = 1000; displayedColumns: string[] = ['serial_no', 'name', 'weight', 'height']; full: boolean = true; @ViewChild(MatSort) sort: MatSort; constructor() { } ngOnInit() { this.getData(); } handleScroll = (scrolled: boolean) => { console.timeEnd('lastScrolled'); scrolled ? this.getData() : _noop(); console.time('lastScrolled'); } hasMore = () => !this.dataSource || this.dataSource.data.length < this.limit; getData() { const data: Element[] = this.dataSource ? [...this.dataSource.data, ...ELEMENT_DATA] : ELEMENT_DATA; this.dataSource = new MatTableDataSource(data); this.dataSource.sort = this.sort; } } In our scroll-component we have created the methods to implement infinite scrolling, in these, we have provided some properties to an item to function with scrolling like the following: infiniteScroll is the primary property that defines the content that is scrolling through. infiniteScrollDistance is Used to provide the distance where we will reach the defined percentage of the item, at which time the scrolling event will be triggered. infinteScrollThrottle indicates the number of milliseconds after the scrolling event will be triggered. Scrolled is a method for carrying out a specific action when scrolling is reached. In scrollWindow, we should decide if we want to listen to the window scroll or scroll event. So, these are some of the properties we used in this demonstration project, but we can use more methods or properties depending on our requirements. So, our code main to implement infinite scrolling is in our scroll-container like the following: Scroll-container.component.ts import { Component, OnInit, OnChanges, Input, Output, EventEmitter, HostListener, ElementRef } from '@angular/core'; import { throttle as _throttle, noop as _noop } from "lodash-es"; enum ScrollDirection { UP = 'up', DOWN = 'down' } enum ScrollListener { HOST = 'scroll', WINDOW = 'window:scroll' } @Component({ selector: 'app-scroll-container', templateUrl: './scroll-container.component.html', styleUrls: ['./scroll-container.component.css'] }) export class ScrollContainerComponent implements OnInit, OnChanges { private _element: Element; private _window: Element; public scrollTop = 0; @Input() more = true; @Input() scrollDelay = 500; @Input() scrollOffset = 1000; @Output() scrolled: EventEmitter = new EventEmitter(); @HostListener(ScrollListener.HOST) _scroll: Function; @HostListener(ScrollListener.WINDOW) _windowScroll: Function; constructor(private elRef: ElementRef) { this._element = this.elRef.nativeElement; this._window = document.documentElement as Element; } ngOnInit() { this.setThrottle(); } ngOnChanges(changes) { if (changes.scrollDelay) this.setThrottle(); } setThrottle() { this._scroll = this._windowScroll = _throttle(this.handleScroll, this.scrollDelay); } getListener = () => this.elRef.nativeElement.clientHeight === this.elRef.nativeElement.scrollHeight ? ScrollListener.WINDOW : ScrollListener.HOST roundTo = (from: number, to: number = this.scrollOffset) => Math.floor(from / to) * to; getScrollDirection = (st: number) => this.scrollTop <= st ? ScrollDirection.DOWN : ScrollDirection.UP; canScroll(e: Element): boolean { const scrolled = this.more && this.getScrollDirection(e.scrollTop) === ScrollDirection.DOWN && this.roundTo(e.clientHeight) === this.roundTo(e.scrollHeight - e.scrollTop); this.scrollTop = e.scrollTop; return scrolled; } handleScroll = () => this.getListener() === ScrollListener.HOST ? this.scrolled.emit( this.canScroll(this._element) ) : this.scrolled.emit( this.canScroll(this._window) ) } Scroll-container.component.html Looking for Trusted Angular Development Company? Enquire Today. See here Our app.module.ts file looks like the following App.module.ts import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MatTableModule, MatSortModule, MatProgressSpinnerModule } from '@angular/material'; import { AppComponent } from './app.component'; import { HelloComponent } from './hello.component'; import { ScrollContainerComponent } from './scroll-container/scroll-container.component'; @NgModule({ imports: [ BrowserModule, FormsModule, BrowserAnimationsModule, MatTableModule, MatSortModule, MatProgressSpinnerModule ], declarations: [ AppComponent, HelloComponent, ScrollContainerComponent ], bootstrap: [ AppComponent ] }) export class AppModule { } Output When we execute our project, we can see the output on the following screen.   Figure 1: Output screen of our infinite scroller demo   Figure 2: Output screen after scrolling Conclusion In this blog, we have discussed ngx infinite scrolling, discussed its properties and methods for implementing it. We have also implemented the demonstration project for a better understanding of it.
Kapil Panchal

Kapil Panchal

A passionate Technical writer and an SEO freak working as a Content Development Manager at iFour Technolab, USA. With extensive experience in IT, Services, and Product sectors, I relish writing about technology and love sharing exceptional insights on various platforms. I believe in constant learning and am passionate about being better every day.

Build Your Agile Team

Enter your e-mail address Please enter valid e-mail

Categories

Ensure your sustainable growth with our team

Talk to our experts
Sustainable
Sustainable
 
Blog Our insights
10 Executive Dashboard Examples for Consultants and CEOs
10 Executive Dashboard Examples for Consultants and CEOs

There is a principle behind every business. “If you don’t keep track of essentials, you won’t get clear direction, eventually causing your company to stumble.” To manage this scenario,...

How Spatial Data Analysis Improves Healthcare
How Spatial Data Analysis Improves Healthcare

Do you know when geospatial analysis took traction in healthcare? It was when John Snow, a London-based physician, used it to analyze the spread of cholera, which ultimately proved...

4 Types of Power BI Dashboards: Analytical, Strategic, Operational, and Tactical
4 Types of Power BI Dashboards: Analytical, Strategic, Operational, and Tactical

One interesting aspect you truly love about Power BI, as a CTO, is how it lets you step back and see the bigger picture of your business. Isn’t it? Without getting bogged down in minute...