Angular RxJS with Paging

Overview

The following guide shows how to create an Angular application using RxJS library and our DataGrid component. In the example, we will implement Server Paging.

angular datagrid rxjs observable

The Angular application that we are going to create will use Smart Angular GridComponent, The purpose of the application is to demonstrate how to use RxJS with Smart.Grid.

The RxJS library

RxJS is a library for composing asynchronous and event-based programs by using observable sequences. It provides one core type, the Observable, satellite types (Observer, Schedulers, Subjects) and operators inspired by Array#extras (map, filter, reduce, every, etc) to allow handling asynchronous events as collections. RxJS provides an implementation of the Observable type.

Project Configuration

  1. Create a new Angular project with the following command:
    ng new smart-project
    
  2. Add Smart UI for Angular to your project
    ng add smart-webcomponents-angular
    
  3. Edit src/app/app.module.ts
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { GridModule } from 'smart-webcomponents-angular/grid';
    import { AppComponent } from './app.component';
    import { FormsModule } from '@angular/forms';
    import { HttpClientModule } from '@angular/common/http';
    
    @NgModule({
        declarations: [ AppComponent ],
        imports: [ BrowserModule, FormsModule, GridModule, HttpClientModule ],
        bootstrap: [ AppComponent ]
    })
    
    export class AppModule { }
    
  4. Edit src/app/app.component.html

    It defines the Grid and its properties.
    <smart-grid #grid id="grid"  [paging]="paging"  [pager]="pager" [appearance]="appearance" [behavior]="behavior" [dataSource]="dataSource" [columns]="columns"></smart-grid>
    
  5. Edit src/app/app.component.css

    In this file, we define the styles of the DataGrid and its columns.
    /* This is the CSS used in the demo */
    /* This is the CSS used in the demo */
    smart-grid {
        width: 100%;
    }
    
    .change-container,
    .value-container {
        display: block;
    }
    
    .change-container {
        display: flex;
        margin-right: 5px;
    
    }
    
    .change-container.negative {
        color: rgb(229, 57, 53);
    }
    
    .change-container.positive {
        color: rgb(67, 160, 71);
    }
    
    .change-container::before {
        content: var(--smart-icon-up);
        width: 100%;
        height: 100%;
        font-family: var(--smart-font-family-icon);
        font-style: normal;
        font-weight: normal;
        font-size: var(--smart-arrow-size);
        color: inherit;
        text-decoration: inherit;
        font-variant: normal;
        text-transform: none;
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;
        position: relative;
        margin-right: 5px;
    }
    
    .change-container.negative::before {
        transform: rotate(180deg);
    }
    
    .value-container {
        padding: 3px;
        background-color: rgb(30, 102, 90);
        color: white;
    }
    
    .smart-grid-cell-template {
        padding-right: 5px;
    }
    
    .smart-grid-cell-template[column="price"] {
        display: flex;
        align-items: center;
        height: 100%;
        line-height: 1;
        margin-left: 10px;
    }
    
  6. Edit src/app/app.component.ts

    In the code we load the initial data via a Observable subscription. The data updates are through another Observable subscription each time the current page index is changed.
    import { Component, ViewChild, AfterViewInit, ViewEncapsulation } from '@angular/core';
    import { GridComponent, GridColumn, DataAdapter, Smart } from 'smart-webcomponents-angular/grid';
    import { Observable, from  } from 'rxjs';
    
    @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['app.component.css'],
        encapsulation: ViewEncapsulation.None
    })
    
    export class AppComponent implements AfterViewInit {	
    	@ViewChild("grid", { read: GridComponent, static: false }) grid!: GridComponent;
    
    	pager = {
    		visible: true
    	};
    	
    	paging = {
    		enabled: true
    	};
    	
    	// setup Datagrid appearance.
    	appearance = {
            alternationCount: 2,
            showColumnLines: false,
            showColumnHeaderLines: false
        };
    	
    	// setup Datagrid columns resize.
        behavior = { columnResizeMode: 'growAndShrink' };
      
        // setup Datagrid data source.  
        dataSource = new window.Smart.DataAdapter({
            dataSource: [],
            dataFields: [
                'commodity: string',
                'price: number',
                'priceChange: number',
                'day: number',
                'week: number',
                'month: number',
                'year: number',
                'date: date'
            ]
        });
    	
    	// setup Datagrid columns.
        columns = [
            { label: 'Commodity', dataField: 'commodity' },
            {
                label: 'Price', dataField: 'price', align: 'left', cellsAlign: 'left'
            },
            { label: 'Weekly', dataField: 'week' },
            { label: 'Monthly', dataField: 'month' },
            { label: 'Yearly', dataField: 'year' }
        ];
    			
        ngAfterViewInit(): void {	
    		const that = this;
    		
    		// init demo server.
    		const demoServer = this.setupDemoServer(),
    		initServer = demoServer.getData();
    		initServer.subscribe(function(dataRows) {
    
    			that.dataSource = new window.Smart.DataAdapter({
    					virtualDataSourceLength: demoServer.dataRows.length,
    					virtualDataSourceCache: false,
    					virtualDataSource: function(resultCallbackFunction: {(settings: any): void}, details) {
    						demoServer.getData(details.first!, details.last!).subscribe(function(dataRows) {
    							resultCallbackFunction(
    							{
    								dataSource: dataRows
    							});
    						});
    					},
    					dataFields: [
    						'commodity: string',
    						'price: number',
    						'priceChange: number',
    						'day: number',
    						'week: number',
    						'month: number',
    						'year: number',
    						'date: date'
    					]
    				});		
    		});
        }
    	
    	// setup demo server.
    	setupDemoServer() {
    	  function demoServer() {
    		'use strict';
    		this.dataRows = [];
    	  }
    	  
    	  // init server and fetch data from url.
    	  demoServer.prototype.getData = function(first, last) {
    		return from(
    		  new Promise((resolve, reject) => {
    			  fetch('https://raw.githubusercontent.com/HTMLElements/smart-webcomponents-angular/master/data.json')
    			  .then(response => response.json())
    			  .then(data => {
    					let dataSet = data;
    					this.dataRows = dataSet.map((value) => {
    						const newData = Object.assign(value);
    						newData.priceChange = 0;
    						
    						return newData;
    					});
    					
    					if (first === undefined && last === undefined) {
    						resolve(this.dataRows);
    					}
    					
    					resolve(this.dataRows.slice(first, last));
    			  });
    		  })
    		);
    	  };
    
    	  return new demoServer();
    	}
    }
    



Angular Datagrid example