"ng6-udm-mock"  JsonPlaceholderとjson-serverを使用するためのAngular6用サービスライブラリ

_ng6-udm-mock_は、JsonPlaceholderとjson-serverをAngular6で使用するためのサービスライブラリです。

## 概要
    - _ng6-udm-mock_ はAngular6によってJsonPlaceholderサービスを利用したい人のためのツールです
    - _ng6-udm-mock_ には、JsonPlaceholderのすべてのテーブル（Post、Comment、Album、Photo、Todo、Userテーブル）のデータを取得、追加、更新、削除するメソッドがあります。
    - _json-server_ を使用して独自のデータをテストできます
    - アクセス先を環境変数で変更することができます

_ビデオ解説 (日本語)_,
<https://youtu.be/AsVctVk0Hxk>

_ビデオ解説 (英語)_,
<https://youtu.be/qt6TsDoQR7g>

## 登録メソッド

このライブラリに登録されているメソッドは以下のとおりです。

```bash

  // =============== Post ================
  public getAllPosts(): Observable<UdmPost[]>
  public getPost(id: number): Observable<UdmPost>
  public getPostsByUserId(userId: number): Observable<UdmPost[]>
  public addPost(userId: number, title: string, body: string): Observable<HttpResponse<UdmPost>>
  public updatePost(post: UdmPost): Observable<number>
  public deletePost(post: UdmPost | number): Observable<number>

  // =============== Comment ================
  public getAllComments(): Observable<UdmComment[]>
  public getComment(id: number): Observable<UdmComment>
  public getCommentsByPostId(postId: number): Observable<UdmComment[]>
  public addComment(postId: number, name: string, email: string, body: string): Observable<HttpResponse<UdmComment>>
  public updateComment(comment: UdmComment): Observable<number>
  public deleteComment(comment: UdmComment | number): Observable<number>

  // ============== Album ==========================
  public getAllAlbums(): Observable<UdmAlbum[]>
  public getAlbum(id: number): Observable<UdmAlbum>
  public getAlbumsByUserId(userId: number): Observable<UdmAlbum[]>
  public addAlbum(userId: number, title: string): Observable<HttpResponse<UdmAlbum>>
  public updateAlbum(album: UdmAlbum): Observable<number>
  public deleteAlbum(album: UdmAlbum | number): Observable<number>

  // ============== Photo ==========================
  public getAllPhotos(): Observable<UdmPhoto[]>
  public getPhoto(id: number): Observable<UdmPhoto>
  public getPhotosByAlbumId(albumId: number): Observable<UdmPhoto[]>
  public addPhoto(albumId: number, title: string, url: string, thumbnailUrl: string): Observable<HttpResponse<UdmPhoto>>
  public updatePhoto(photo: UdmPhoto): Observable<number>
  public deletePhoto(photo: UdmPhoto | number): Observable<number>

  // ============== Todo ==========================
  public getAllTodos(): Observable<UdmTodo[]>
  public getTodo(id: number): Observable<UdmTodo>
  public getTodosByUserId(userId: number): Observable<UdmTodo[]>
  public addTodo(userId: number, title: string, completed: boolean ): Observable<HttpResponse<UdmTodo>>
  public updateTodo(todo: UdmTodo): Observable<number>
  public deleteTodo(todo: UdmTodo | number): Observable<number>

  // ============== User ==========================

  public getAllUsers(): Observable<UdmUser[]>
  public getUser(id: number): Observable<UdmUser>
  public getUsersByUserName(username: string): Observable<UdmUser[]>
  public addUser(name: string,
                username: string,
                email: string,
                address: UdmAddress,
                phone: string,
                website: string,
                company: UdmCompany ):
                Observable<HttpResponse<UdmUser>>
  public updateUser(user: UdmUser): Observable<number>
  public deleteUser(user: UdmUser | number): Observable<number>

```

## 登録インターフェイス

このライブラリに登録されているインターフェイスは以下のとおりです。


```typescript

export interface UdmPost {
    id: number;
    userId: number;
    title: string;
    body: string;
}

export interface UdmComment {
    id: number;
    postId: number;
    name: string;
    email: string;
    body: string;
}

export interface UdmAlbum {
    id: number;
    userId: number;
    title: string;
}

export interface UdmPhoto {
    id: number;
    albumId: number;
    title: string;
    url: string;
    thumbnailUrl: string;
}

export interface UdmTodo {
    id: number;
    userId: number;
    title: string;
    completed: boolean;
}

export interface UdmGeo {
    lat: string;
    lng: string;
}

export interface UdmAddress {
    street: string;
    suite: string;
    city: string;
    zipcode: string;
    geo: UdmGeo;
}


export interface UdmCompany {
    name: string;
    catchPhrase: string;
    bs: string;
}

export interface UdmUser {
    id: number;
    name: string;
    username: string;
    email: string;
    address: UdmAddress;
    phone: string;
    website: string;
    company: UdmCompany;
}

```

## 稼働環境

   - Node.js
   - TypeScript2
   - Angular6
   - json-server (データの追加、変更、削除機能を利用したい場合)



## インストール方法


このライブラリをインストールするには、以下のように実行します。

```bash

$ npm install ng6-udm-mock --save

```

_json-server_をインストールするには、以下のように実行します。

```bash

$ npm install json-server 

```


## 設定方法


ライブラリ自体には、サーバのアクセス先が設定されていません。このアクセス先は、このライブラリを使用するアプリケーションプロジェクトの環境変数によって設定します。 具体的には、 `src/environments/environment.ts`ファイルに設定します。

_JsonPlaceholder_サイトにのみアクセスしてデータを取得する場合は、_udmMockBaseUrl_に `https：//jsonplaceholder.typicode.com`を設定します。

データの追加、更新、削除機能を使用する場合は、JsonPlaceholderサイトのデータと同じ構造の独自のデータを作成し、_json-server_を起動し、そのサーバのアクセス先を_udmMockBaseUrl_に設定します。

ポート番号を指定せずにサーバをローカルに起動すると、デフォルトで`localhost：3000`がアクセス先になりますので、その場合はこれを設定します。



### `environment.ts`ファイルにおけるアクセス先の設定例


```typescript

export const environment = {
  production: false,
  udmMockBaseUrl: 'https://jsonplaceholder.typicode.com'
  // udmMockBaseUrl: 'http://localhost:3000'
};

```


### サンプルプログラム `app.component.ts`

以下は、このライブラリを使用するサンプルプログラムです。

　重要な点は次のとおりです。

- Ng6UdmMockServiceをインポートする
- インターフェイスをインポートする
- 各インタフェースに対応する変数（配列を含む）を定義する
- コンストラクタでサービス変数を作成する
- ngOnInitメソッドでBaseUrlを初期化する（setBaseUrlメソッドを呼び出す）

　なお、コンポーネント・ライブラリの場合は、`app.module.ts`ファイルへの登録が必要になりますが、本ライブラリは、サービス・ライブラリですので、その登録は不要です。
　これらの点に留意して、以下のソースを参照してください。

```typescript

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { tap, map } from 'rxjs/operators';
import { HttpErrorResponse } from '@angular/common/http';

import { Ng6UdmMockService } from 'ng6-udm-mock';
import { UdmPost, UdmComment, UdmAlbum, UdmPhoto, UdmTodo,
  UdmGeo, UdmAddress, UdmCompany, UdmUser } from 'ng6-udm-mock';

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

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

  private posts: UdmPost[];
  private post: UdmPost;
  private comments: UdmComment[];
  private comment: UdmComment;
  private albums: UdmAlbum[];
  private album: UdmAlbum;
  private photos: UdmPhoto[];
  private photo: UdmPhoto;
  private todos: UdmTodo[];
  private todo: UdmTodo;
  private users: UdmUser[];
  private user: UdmUser;

  constructor(private sv: Ng6UdmMockService) {

  }

  ngOnInit() {
    this.sv.setBaseUrl(environment.udmMockBaseUrl);
  }
// ============== Post ==================

  public GetAllPosts() {
    this.sv.getAllPosts()
      .subscribe(
        dt => {
          this.posts = dt;
        },
        (err: HttpErrorResponse) => {
          if (err.error instanceof Error) {
            console.log('An error occurred:', err.error.message);
          } else {
            console.log('Status code:', err.status);
            console.log('Response body:', err.error);
          }
        },
        () => {
          console.log('Done successfully');
        }
      );
  }

  public GetPost(id: number) {
    this.sv.getPost(id)
    .subscribe(
      dt => {
        this.post = dt;
      },
      (err: HttpErrorResponse) => {
        if (err.error instanceof Error) {
          console.log('An error occurred:', err.error.message);
        } else {
          console.log('Status code:', err.status);
          console.log('Response body:', err.error);
        }
      },
      () => {
        console.log('Done successfully');
      }
    );
  }

  public GetPostsByUserId(userId: number) {
    this.sv.getPostsByUserId(userId)
    .subscribe(
      dt => {
        this.posts = dt;
      },
      (err: HttpErrorResponse) => {
        if (err.error instanceof Error) {
          console.log('An error occurred:', err.error.message);
        } else {
          console.log('Status code:', err.status);
          console.log('Response body:', err.error);
        }
      },
      () => {
        console.log('Done successfully');
      }
    );
  }

  public AddPost(userId: number, title: string, body: string) {
    this.sv.addPost(userId, title, body)
    .subscribe(
      dt => {
        this.post = dt.body;
      },
      (err: HttpErrorResponse) => {
        if (err.error instanceof Error) {
          console.log('An error occurred:', err.error.message);
        } else {
          console.log('Status code:', err.status);
          console.log('Response body:', err.error);
        }
      },
      () => {
        console.log('Done successfully');
      }
    );
  }

  public UpdatePost() {
    const post: UdmPost = {
      id: 4,
      userId: 1,
      title: 'test01 - updated 01',
      body: 'This is updated text'
    };
    this.sv.updatePost(post)
    .subscribe(
      dt => {
        console.log(dt);
      },
      (err: HttpErrorResponse) => {
        if (err.error instanceof Error) {
          console.log('An error occurred:', err.error.message);
        } else {
          console.log('Status code:', err.status);
          console.log('Response body:', err.error);
        }
      },
      () => {
        console.log('Done successfully');
      }
    );
  }

  public DeletePost() {
    this.sv.deletePost(4)
    .subscribe(
      dt => {
        console.log(dt);
      },
      (err: HttpErrorResponse) => {
        if (err.error instanceof Error) {
          console.log('An error occurred:', err.error.message);
        } else {
          console.log('Status code:', err.status);
          console.log('Response body:', err.error);
        }
      },
      () => {
        console.log('Done successfully');
      }
    );
  }

```


## バージョン

   - ng6-udm-mock : 3.0
   - node.js      : 8.11
   - @angular/cli : 6.0
   - TypeScript   : 2.7

  

## 参考文献

- "ng6-udm-mock", 
<https://www.npmjs.com/package/ng6-udm-mock>

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

- "HttpClient", 
<https://angular.jp/guide/http>

- "JSON.stringify()", 
<https://www.w3schools.com/js/js_json_stringify.asp>

- "Angular 5, Angular 6 Custom Library: Step-by-step guide", 
<https://www.udemy.com/angular5-custom-library-the-definitive-step-by-step-guide/>

- "Angular 5, Angular 6用 カスタムライブラリの作成: 完全ステップ・バイ・ステップ・ガイド", 
<https://www.udemy.com/angular5-l/>