<file_sep>import { Ng6UdmMockService } from 'ng6-udm-mock';
import { UdmCommentDataSource } from './udm-comment-datasource';
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
import { MatPaginator, MatSort } from '@angular/material';
import { tap } from 'rxjs/operators';

import { environment } from '../../environments/environment';

@Component({
  selector: 'app-udm-table',
  templateUrl: './udm-table.component.html',
  styleUrls: ['./udm-table.component.css']
})
export class UdmTableComponent implements AfterViewInit, OnInit {
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;
  commentDataSource: UdmCommentDataSource;

  displayedColumns = ['id', 'postId', 'name', 'email', 'body'];
  // displayedColumns = ['id', 'postId', 'name', 'email'];

  constructor(private sv: Ng6UdmMockService) {

  }

  ngOnInit() {
    this.sv.setBaseUrl(environment.udmMockBaseUrl);
    this.commentDataSource = new UdmCommentDataSource(this.paginator, this.sort, this.sv);
    this.commentDataSource.loadComments();
  }

  private loadComments() {
    this.commentDataSource.loadComments();
  }

  ngAfterViewInit() {
    this.paginator.page
      .pipe(
        tap(() => this.loadComments())
      )
      .subscribe();
  }

}
<file_sep>﻿﻿
# _Ng6UdmMockMatConsumer_ Table with sorting and paging functions based on Angular Material in Angular6
[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)


_Ng6UdmMockMatConsumer_ is a initial set for those who want to make tables with sorting and paging functions by Angular Material in Angular6.

_This full source code_,
<https://github.com/Ohtsu/ng6-udm-mock-mat-consumer>

_Video Explanation (Japanese)_,
<https://youtu.be/AsVctVk0Hxk>

_Video Explanation (English)_,
<https://youtu.be/qt6TsDoQR7g>


## Overview 
   - _Ng6UdmMockMatConsumer_ is a table sample project based on Angular Material in Angular6.

   - _Ng6UdmMockMatConsumer_ uses mat-table, mat-paginator, mat-sort and so on.

   - _Ng6UdmMockMatConsumer_ uses ng6-udm-mock(ver3.0.2) service library for accessing JsonPlaceholder site.
  

## Prerequisite

   - node.js
   - Typescript2
   - Angular6
   - Angular Material
   - ng6-udm-mock


## Installation

To install this project, run simply:

```bash
$ npm install 
```
## Start project

If you start your local server as follows, you can get a table containing the comment data of JsonPlaceholder site  in your browser by accessing **http://localhost:4200**.


```bash
$ ng serve -o
```

  - ***First Page*** 

  <img src="https://raw.githubusercontent.com/Ohtsu/images/master/ng6-material/Table01.gif" width= "900" >


## Version

   - Ng6UdmMockMatConsumer      : 0.1.0
   - Angular6                   : 6.0.3
   - TypeScript                 : 2.7.2
   - @angular/material          : 6.4.7
   - ng6-udm-mock          	: 3.0.2
   


## Reference

- "Schematics", 
<https://material.angular.io/guide/schematics>

- "JsonPlaceholder", 
<https://jsonplaceholder.typicode.com/>

- "Angular 5, Angular 6 Custom Library: Step-by-step guide", 
<https://www.udemy.com/angular5-custom-library-the-definitive-step-by-step-guide/>
 (Discount Coupon until 2018/9/30)
<https://www.udemy.com/angular5-custom-library-the-definitive-step-by-step-guide/?couponCode=NG5-CUSLIB-EN-1001>

- "Angular 5, Angular 6用 カスタムライブラリの作成: 完全ステップ・バイ・ステップ・ガイド", 
<https://www.udemy.com/angular5-l/>
(割引クーポン 2018/9/30まで)
<https://www.udemy.com/angular5-l/?couponCode=NG5-CUSLIB-JA-0930>

- "ng6-udm-mock Angular6 Service Library to use JsonPlaceholder and json-server", 
<https://www.npmjs.com/package/ng6-udm-mock>

- "Reactive Programming with RxJS 5: Untangle Your Asynchronous JavaScript Code", 2018/2/15,<NAME>
<https://www.amazon.co.jp/Reactive-Programming-RxJS-Asynchronous-JavaScript/dp/1680502476/ref=sr_1_7?ie=UTF8&qid=1537063252&sr=8-7&keywords=reactive+programming>

- "Angular Material Data Table: A Complete Example", Angular University
<https://blog.angular-university.io/angular-material-data-table/>

- "Angular 5 Data Table Example(Pagination+Sorting+Filtering)", 2018/01, <NAME>
<https://blog.angular-university.io/angular-material-data-table/>



## Change Log

 - 2018.9.18 version 0.1 uploaded 

## Copyright

copyright 2018 by <NAME> (DigiPub Japan)


## License

MIT © [<NAME>](<EMAIL>)
<file_sep>import { DataSource, CollectionViewer } from '@angular/cdk/collections';
import { MatPaginator, MatSort } from '@angular/material';
import { map } from 'rxjs/operators';
import { Observable, of as observableOf, merge, BehaviorSubject } from 'rxjs';

import { Ng6UdmMockService } from 'ng6-udm-mock';
import { UdmComment } from 'ng6-udm-mock';

export class UdmCommentDataSource extends DataSource<UdmComment> {
    private commentsSubject = new BehaviorSubject<UdmComment[]>([]);

    comments: UdmComment[];

    constructor(private paginator: MatPaginator, private sort: MatSort, private sv: Ng6UdmMockService) {
        super();
    }

    loadComments() {
        this.sv.getAllComments()
            .subscribe(dt => {
                this.commentsSubject.next(dt);
                this.comments = dt;
            });
    }

    connect(collectionViewer: CollectionViewer): Observable<UdmComment[]> {
        const dataMutations = [
            this.commentsSubject.asObservable(),
            this.paginator.page,
            this.sort.sortChange
        ];
        this.paginator.length = this.comments.length;
        return merge(...dataMutations).pipe(map(() => {
            return this.getPagedData(this.getCommentsSortedData([...this.comments]));
          }));
    }

    disconnect(collectionViewer: CollectionViewer): void {
        this.commentsSubject.complete();
    }

    private getPagedData(comments: UdmComment[]) {
        const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
        return comments.splice(startIndex, this.paginator.pageSize);
    }

    private getCommentsSortedData(comments: UdmComment[]) {
        if (!this.sort.active || this.sort.direction === '') {
          return comments;
        }

        return comments.sort((a, b) => {
          const isAsc = this.sort.direction === 'asc';
          switch (this.sort.active) {
            case 'id': return compare(+a.id, +b.id, isAsc);
            case 'postId': return compare(+a.postId, +b.postId, isAsc);
            case 'name': return compare(a.name, b.name, isAsc);
            case 'email': return compare(a.email, b.email, isAsc);
            case 'body': return compare(a.body, b.body, isAsc);
            default: return 0;
          }
        });
      }
}

function compare(a, b, isAsc) {
    return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}
