Angular CLI をアップデートする 

新規マシンにインストールして Anglar CLI のバージョンが結構進んでいたのでこの機会に既存環境もアップデート。既存環境が Angular CLI: 1.7.4 だったので（古いなおい）置いてけぼり感満載で、これはアップデートこけるなと思っていたら（Angularは 5.2.0 だったのでもしかしたらスムーズに行くかもと希望を持ちつつ）案の定こけたので泣きながら作業メモ。

# 作業手順

## 手順

1. グローバルの Angular CLI を削除・インストール
2. ローカル（プロジェクト内の）の Angular CLI をアップデート
3. ビルド通らなくなったので新規プロジェクトを仕方なく作る

## 実作業

### 1. グローバルの Angular CLI を削除・インストール

コマンドミスタイプしたら

```
╭────────────────────────────────────────────────────────────────╮
│                                                                │
│       New minor version of npm available! 6.0.0 → 6.5.0        │
│   Changelog: https://github.com/npm/npm/releases/tag/v6.5.0:   │
│               Run npm install -g npm to update!                │
│                                                                │
╰────────────────────────────────────────────────────────────────╯
```

と言われたので折角なのでグローバルの npm をアップデート。その後にグローバルの Angular CLI を削除。

```
npm uninstall -g @angular/cli
npm cache clean
```

cache clean は必要かよくわからないけどよくやっとけという記事をみるので一応。その後グローバルの Angular CLI をインストール

```
npm install -g @angular/cli
```

### 2. ローカル（プロジェクト内の）の Angular CLI をアップデート

Angular プロジェクトに移動してローカル（プロジェクト内の）の Angular CLI をアップデート

```
ng update @angular/cli
```

上記を終えてとりあえず build してみると

```
The serve command requires to be run in an Angular project, but a project definition could not be found.
```

と怒られた。Angular CLI のどこかのバージョンから `.angular-cli.json` から `angular.json` になったということだったので、新規で作成したプロジェクトから持ってきて、 `.angular-cli.json` で設定した内容を書き込み再度ビルド。すると今度は module が無いやら、Observable の型が無いやら怒り出したのでもうめんどくさいので新規でプロジェクト作ってそこに作成したファイルを設置することに。

### 3. ビルド通らなくなったので新規プロジェクトを仕方なく作る

プロジェクト新規作成後必要ファイルをコピー、`.angular-cli.json` に追記した内容を `angular.json` に書き込んでビルド。

```typescript
import { trigger }          from '@angular/core';
import { transition }       from '@angular/core';
import { style }            from '@angular/core';
import { animate }          from '@angular/core';
```

を書いてる箇所でエラーが出るので、

```typescript
import { trigger }          from '@angular/animations';
import { transition }       from '@angular/animations';
import { style }            from '@angular/animations';
import { animate }          from '@angular/animations';
```

に修正。その後

```
Cannot find module '@angular/http'.
```

で怒られる。`'@angular/http` は廃止になったので手を入れないととは思っていたけど見て見ぬふりしてきましたが...、はい、修正しましょう。

`app.modules.ts` に

```typescript
import { HttpClientModule } from '@angular/common/http';
```

追加、合わせて `@NgModule` の `imports` に追加。次に http 関連を記述している箇所で今回は

```typescript
import { Http } from '@angular/http';
import { Headers} from '@angular/http';
import { RequestOptions} from '@angular/http';
import 'rxjs/add/operator/timeout';
```

を

```typescript
import { HttpClient, HttpHeaders }      from '@angular/common/http';
import { timeout, catchError}           from 'rxjs/operators';
import { Observable, throwError }       from 'rxjs';
```

にして、関連箇所を書き換え。参考までに送信処理は以下のような変更。

```diff
/**
 * httpポスト処理
 * @param {string} _postUrl - 送信URL
 * @param {any} _trans_data - 送信データ
 * @return {any} http.post処理のレスポンス
 */
-  public http(_postUrl: string, _trans_data: any, _options?: RequestOptions): any {
+  public http(_postUrl: string, _trans_data: any): any {
    let ret;
    let postUrl = SystemConst.API_DIR + _postUrl;
-    ret = this._http.post(postUrl, _trans_data, this.options).timeout(SystemConst.TIMEOUT_TIME);
+    ret = this._http.post(postUrl, _trans_data, HTTP_OPTIONS)
+    .pipe(
+      timeout(SystemConst.TIMEOUT_TIME),
+      catchError(this.handleError())
+    );
    return ret;
  }
```

timeout を pipe でやってるのが正解かわからないけどとりあえず動いていてくれているので良しとする。pipe とは関係なしに `postUrl` が間違っていた場合 HTTP ステータスコードの ~~404 が取れないのがちょっと謎（サーバー側の設定の問題な気もする）。現状だとタイムアウト扱いになるのでなんとかしたい。~~とりあえず後は [本家のここ](https://angular.jp/guide/http) や [本家のここ](https://angular.jp/tutorial/toh-pt6)を参考にしつつ以下を追加。

追記: 404 は正しく取得出来ていて、 `handleError()` 内の `return throwError(error.message)` の後に独自実装していた処理で return値 `error.message` から status を取得しようとしていたのが問題でした。　`error` 内にはちゃんと `status` を持っておりました。

```typescript
const HTTP_OPTIONS = {
  headers: new HttpHeaders({
    'Content-Type':  'application/json'
  })
};
```

```typescript
/**
 * Observable のエラーを返却します
 * @param 無し
 * @return {Observable<any>}
 */
private handleError() {
  return (error: any): Observable<any> => {
    // 強制的にトップに移動
    this.scrollTop();
    return throwError(error.message);
  };
}
```

以上でとりあえずもとのように動く状態になったと思われる。

バージョンアップでビルドエラー出ると普通に胃が痛くなって嫌なのですが RxJS やら Observable やらがあまり理解出来ていなったけどちょっと理解できたので良かったぞなもし。RxJS の概念的な説明は [RxJS を学ぼう #1 - これからはじめる人のための導入編](https://tech.recruit-mp.co.jp/front-end/rxjs-intro/) が短くまとまっている割にわかりやすかったです。

次は実装整理を兼ねて具体的に[何か作りながらアウトプッ](https://qiita.com/koronpo/items/1f93f4dfbd75ecf9cb95)トしたいところ。