Angular7 + Bootstrap4 で Web アプリを作ろう - ngx-translate で他言語化の件 。
こんにちはふるてつです。
今日は土曜日、ちょっとくもり。わたしは家でAngularを自習しています。
今回のテーマは他言語です。
勤務先で ngx-translate を使って他言語化した方がいて、話を聞いていると思ったより簡単そうだと感じました。
Angular純正もあったかと思いましたが、ネットでも ngx-translate がよさそうとの評もあり今回試してみました。
https://qiita.com/daikiojm/items/def764b12c8ff2ebbc92
ngx-translate のインストール
まず下記の CLI コマンドでインストールします。
https://github.com/ngx-translate/core (Gitリポジトリ)を参考にして設定します。
ngx-translate の core と http-loader が必要そうです。
両方ともにインストールします。
npm install @ngx-translate/core --save npm install @ngx-translate/http-loader --save
なぜ@を ngx-translate/core の前につけるかというと「node_modules」フォルダの中に@付きでライブラリを入れるためです。
言い換えると他のライブラリと区別しやすくするためです。
インストール完了後のターミナル
もうひとつ。サクッとうまくいきました。
package.json には ngx-translate/core が追加されました。
package-lock.json も変わりました。
AppModule クラスの修正
まずAppモジュールの中に TranslateModule の import を追加します。
このあたりの設定は Git リポジトリの README.MD の 中段あたり Configuration のところに書いてあります。
TranslateHttpLoader
というクラスを使用して、HTTPで 他言語用の json ファイルを読み込んで変換します。
json ファイルは "/assets/i18n/[lang].json" に置く感じになります。
TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, deps: [HttpClient] } })
あと TranslateHttpLoader を返すメソッドを一つ追加しました。 これも手順通りです。
export function HttpLoaderFactory(http: HttpClient) { return new TranslateHttpLoader(http, './assets/i18n/', '.json'); }
AppModule クラスのコード全体は下記になりました。
// 機能に関するモジュール類 import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { FormsModule } from '@angular/forms'; import { environment } from '../environments/environment'; import { HttpClientModule, HttpClient } from '@angular/common/http'; import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; // コンポーネント関連 import { AppComponent } from './app.component'; import { HeaderComponent } from './component/common/header/header.component'; import { FooterComponent } from './component/common/footer/footer.component'; import { SignInComponent } from './component/pages/sign-in/sign-in.component'; import { EvaluationResultComponent } from './component/pages/evaluation-result/evaluation-result.component'; import { SearchInfoComponent } from './component/common/search-info/search-info.component'; import { MessagesComponent } from './component/common/message/messages/messages.component'; import { ErrorMessagesComponent } from './component/common/message/error-messages/error-messages.component'; // 他言語化の設定 export function HttpLoaderFactory(http: HttpClient) { return new TranslateHttpLoader(http, './assets/i18n/', '.json'); } // モジュール定義 @NgModule({ declarations: [ AppComponent, HeaderComponent, FooterComponent, SignInComponent, EvaluationResultComponent, SearchInfoComponent, MessagesComponent, ErrorMessagesComponent ], imports: [ BrowserModule, NgbModule.forRoot(), FormsModule, AppRoutingModule, HttpClientModule, TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, deps: [HttpClient] } }) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
上のコードが長くなり見にくくスミマセン。
AppModule クラスの修正
次は一旦 AppComponent のコンストラクタで TranslateService をインジェクトして、日本語を使用するよう設定しておきます。
今後どのようにするかまだ決めていませんが、ブラウザの言語設定に合わせて切り替えるか?
DBにユーザ毎の言語設定を登録して切り替えるか?どちらかにすると思います。
AppComponent クラスのコードは下記になります。
コンストラクタで TranslateService をインジェクトしてデフォルトの言語と使用する言語を設定しました。
import { Component } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'sanrokumaru'; constructor(translate: TranslateService) { // 言語の初期設定 translate.setDefaultLang('en'); translate.use('ja'); } }
json ファイルの作成
assets/i18n/に en.json と ja.json 2ファイルを作ります。
json の中身は下記です。
フォーマットを間違えなければ、どういうまとめ方でも構わないと思います。
{ "welcomeScreen": { "title": "ようこそ", "systemName": "Sanrokumaruシステムへ", "comment": "より良いコミュニケーションを目指して" }, "signInScreen": { "signIn": "サインイン", "userId": "ユーザID", "password": "パスワード", "signInBtn": "サインイン", "information": "お知らせ" } }
html の書き換え
あとは html の中で直に文言を書き込んでいる個所を書き換えるだけです。
まずは簡単な書き方です。下記のような label の例になります。
タグの中に translate を追記し文言を json のキーに置き換えます。
<label for="loginUserId">ユーザID</label> ↓ 変更後 <label for="loginUserId" translate>signInScreen.userId</label>
次はちょっと難しい分。例はプレースホルダーになります。 {{}}の中に json のキーを追記し、パイプで translate をするように書きます。
<input id="loginUserId" type="text" placeholder="ユーザID"> ↓ 変更後 <input id="loginUserId" type="text" placeholder="{{ 'signInScreen.userId' | translate }}">
あとは大体似たような感じで、サインイン画面の文言を他言語化しました。
日本語の時は下記
英語の時は下記のようになります。
今日の感想
今日は ngx-translate を使って他言語化にチャレンジしました。
1画面だけですが思ったより簡単にできました。
コードを書くよりこのブログを書く方に時間がかかったくらいです。
今後の他言語化は全部これで行こうか~と思いました。
では、今日もお疲れ様でした。
Angular7 + Bootstrap4でWebアプリを作ろう - サービスその2 HTTP通信。
こんにちはふるてつです。
今日は Angular です
前回の社内もくもく会でモックサービスを作りました。
そして今回はそれを HTTP 通信で取得するように変えました。
サーバ側は先日環境を作った Spring Boot にしています。
まずは定数を格納するクラスを作る所から始めます。
appConstクラスを追加
まずはサーバのURLなど固定値専用のクラスを作ります。下記の CLI コマンドで作ります。
固定値だけなのであとでテストファイル 「xxx.spec.ts」 は消しました。
ng generate class appConst
① AppConst クラスにローカルで実行するときのサーバURLを追加します。
② HTTP 接続する際に、クロスオリジン制約にかからないようプリフライトリクエストを送る必要があります。
プレフライトリクエスト用の HTTP オプションを一ヶ所に持ち、各サービスで使いまわします。
プレフライトリクエストについてはこちらが分かりやすいかもですhttps://qiita.com/rooooomania/items/4d0f6275372f413765de
○ appConst クラスの内容
import { HttpHeaders } from '@angular/common/http'; export class AppConst { // サーバー URL static readonly URL_DEV_SERVER = 'http://localhost:8080/api/'; // HTTP オプション(プレフライトリクエスト) static readonly httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; }
information サービスの修整
information サービスは下記のように修正しました。
① AppConst クラスからローカルテスト用のサーバURLを取得して private 変数で持つ。
② api のエンドポイント名を private 変数で持つ "informations"
③コンストラクタの引数に private http: HttpClient を追加して、HTTP CLIENTをインジェクトする。
④あとは最後の行で Spring Boot に HTTP通信して json データを取得する。
http はコンストラクタでインジェクトしているので、this で呼び出せる。
this.http.get<Information[]>() メソッドの第2引数には
先ほど作ったプリフライトリクエスト用のHTTP オプションを渡す。
○ information サービスクラスの内容
import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { Information } from 'src/app/entity/domain/information'; import { environment } from '../../../environments/environment'; import { AppConst } from '../../app-const'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class InformationService { private server = environment.production ? AppConst.URL_PROD_SERVER : AppConst.URL_DEV_SERVER; private webApiUrl = 'informations'; constructor(private http: HttpClient) { } getInformations(): Observable<Information[]> { console.log(this.server + this.webApiUrl); return this.http.get<Information[]>(this.server + this.webApiUrl, AppConst.httpOptions); } }
Spring Boot の設定
Spring Boot のコントローラに対し、クロスオリジンを許すようにします。
○ Spring Boot のコントローラ内容
@CrossOrigin
アノテーションをコントローラにつけてクロスオリジンを許可します。
@RestController @RequestMapping("api/informations") @CrossOrigin public class InformationRestController { @GetMapping public List<InformationDto> getInformations(){ return informationService.searchAll(); } }
Spring Bootの設定を変えてクロスオリジンを許すようにしました。
これで準備完了です。
あとは Angular と Spring Boot を共に起動して HTTP 通信でデータの疎通を確認して終わりました。
今日の感想
今日はモックでなく、HTTPで実際に通信してデータを取得するようにしてみました
これでやっと Angular を動かしている気になってきました。
当面はこれで行こうかと思います。
しかしチュートリアルと比較するとエラー時のハンドリングが足りないようです。
チュートリアルではサービスで http.get メソッドを動かした後、
observable の結果を pipe() で拡張して、それを catchError() オペレーターに渡してますねぇ。
通信に失敗した時など必要そうなので、最終的にはその形にリファクタリングしたいと思いました。
では、お疲れ様でした。
今夜は社内AWSもくもく会 - EC2その2 インスタンスの作成とSSH、HTTPアクセスの許可
こんにちはふるてつです。
今回も社内 AWS もくもく会の内容です。EC2 の利用その2です。
今回のテーマは EC2 の作成と SSH ログイン、HTTP アクセスの許可です。
前回はセキュリティグループの作成などを行いましたが、
これでやっとすこし進んだ気がします。
EC2 作成
まずは EC2 のダッシュボード画面。まだ実行中のインスタンスは何もありません。
画面中段の「インスタンスの作成」ボタンを押してインスタンスを作り始めます。
マシンイメージを選ぶ画面が出てきます。もちろん無料利用枠の中から選びます。
Amazon Linux だと2種類あります。
「Amazon Linux 2 AMI (HVM), SSD Volume Type」と「Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type」です。
どちらにするか少し迷ったのですが、今回はわたしが参考にしている本と同じく「Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type」を使用します。
上から2段目です。長く使うのであれば新しい方(Amazon Linux 2 AMI)が良いとは思いますが。
インスタンスタイプを選択する画面が出てきます。
無料枠の「t2.micro」を選びます。
選んだあと「インスタンス詳細の設定」ボタンをクリックします。
インスタンス詳細の設定画面では「ネットワーク」欄と「サブネット」欄、「自動割り当てパブリックIP」を設定します。
「ネットワーク」欄と「サブネット」欄はどちらもこれまでに作ってきたものを選択します。
「自動割り当てパブリックIP」は "有効化" にします。
上記以外はデフォルトのままにしておきます。
ストレージもデフォルトのまま。
タグは「キー」欄に "Name" と入力し、EC2 インスタンスに好きな名前を設定しておきます。
セキュリティグループの設定画面では、前回作成したセキュリティグループを設定します。
そして「確認と作成」ボタンをクリックする。
この画面で「確認」。
次は下の画面のようにキーペアについて聞かれます。
ここは既存のキーペア(前回作成したもの)をもちろん選択します。
「インスタンスの作成」ボタンをクリックすると、AWS が EC2 インスタンスを作り始めます。
まだ作成中…
インスタンスの状態が下記の感じ(runnning)になったら出来上がりです。
SSH接続
では次に SSH で先ほどの EC2 にログインします。
本では TeraTerm を使っています、わたしもずっと TeraTerm です。
若い方は RLonin などを使われているかもしれませんね。
今回は TeraTerm を起動します。
ホスト欄にはパブリック DNS を設定しておきます。
パブリック DNS は、上記の EC2 インスタンスの一覧画面の右下に表示されています。
こちらをコピー/ペーストで構いません。
「OK」をクリックすると。
SSH認証の画面がでてきます。
「ユーザー名」は「ec2-user」(EC2 にデフォルトで存在するユーザです)
「秘密鍵」の欄は前回作成したキーペアファイルを指定します。
(このキーペアファイルは誰にも渡してはなりません)
これで「OK」を押すとつながるはずです。
繋がりました。コマンドが打てるようになりました。
HTTPサーバーをインストールしてアクセスを試してみる
ここからはただのテストですが、EC2 に Apache をインストールして http でアクセスしてみます。
まずは Apache のインストール。yum です。
chkconfig コマンドは今後自動で Apache を起動するために実行します。
sudo yum install httpd -y sudo service httpd start sudo chkconfig httpd on
次はセキュリティグループの再設定
80番ポートを開くよう「ルールの追加」をクリックします。
タイプ "HTTP" を "任意の場所" で追加します。そして「保存」をクリック。
下のように「インバウンド」のルールに "HTTP" が2件ほど追加されました。
上が IPv4 用の設定で、下が IPv6 用の設定です。どちらもすべてを許可する設定です。
(本日一緒に勉強している者から聞きました)
あとはローカルマシンのブラウザから EC2 インスタンスのパブリック DNS にアクセスしてみると TestPage が表示されます。
感想
やっと今回 EC2 のインスタンスを作りました。
一応 SSH も HTTP もつながるようになりました。すこし進んだ気になりちょっぴり嬉しいです。
この先は ELB(ロードバランサ)などが出てくるようです。楽しみですねぇ
ではでは
Angular7 + Bootstrap4でWebアプリを作ろう - 今夜はSpring Bootだけ 環境作りからモックのREST APIを1本作るまで。
こんにちはふるてつです。
Angular でサービスを作るようになり、そろそろサーバが欲しくなってきました。
そこで今日は Spring Boot 環境を作りAPIを1本作るまでを行いたいと思います。
なぜ Spring かというとそれしかできないからですね。選択の余地ありません…
環境の準備(Eclipseのダウンロード)
まずは環境を整えます。何度やっても、わたしはやり方をすぐ忘れちゃいますね。
①Eclipseのダウンロード
まずは基本的なところで Eclipse のダウンロードから始めます。
オールインワンを使いたく。下記のURLですね。
http://mergedoc.osdn.jp/
今回は「4.8 Photon」を使います。クリックします。
ダウンロードする Eclipse ですが、わたしは迷わず「Java」の「Full Edition」を選びます。
エディションについて「Standard Edition」を選び必要なプラグインを入れるやり方もありますが、
大雑把な私には向いてませんので。
上記の画面でダウンロードしたZIPファイルを展開すると Eclipse が出てきます。
(ZIPから解凍するときに回答先のフォルダ名が長かったり階層が深すぎると展開時にエラーメッセージが出るので注意しましょう)
あと日本語化もしておきましょう。職場では Eclipse は英語版と決まっているのですが、個人的には日本語が落ち着きます。
同じサイトからダウンロードしてきた下記のツールを起動します。
「日本語化するアプリケーション」欄に 日本語化したいEclipse の exe ファイルを選択して実行するのみです。
②Spring Boot プラグインと DBeaver プラグインの追加
次はSpring Boot プラグインを Eclipse に追加します。
「メニュー」→「ウィンドウ」→「マーケットプレイス」から「sts」を検索するとプラグインが出てきます。
下のような画面になります。
そもそも Spring Tool Suite (STS) を使う方法もありますが、オールインワンに Spring Boot プラグインを入れる方が Eclipse のバージョンを選べ、こちらのほうがわたしは良いとか思っています。
あと開発時は H2 DB を使いたいので、DBeaver プラグインをいれておきます。これはH2 DB の中身を見るためのツールです。
H2 を使わなければ不要です(本番は PostgreSQL の RDS にする予定ですが)
③Lombokのインストール
Lombok を使用したいのでインストールします(例の getter/setter などを勝手につくってくれるプラグインです)
下記のURLからダウンロードします。 https://projectlombok.org/
このサイトのメニューからダウンロードを選びます。
下の画面にて最新バージョンらしき「1.18.6」をダウンロードします。
中にインストーラーが入っていますので、起動します。
起動してすぐに自分のマシン中の Eclipse を捜しだそうとするようですが、時間がかかり待っていられないので、わたしはいつも手動で Eclipse の場所を指定します。
中段の「Specify location…」ボタンがそれです。Eclipse の exeファイルを選択して「Install / Update」を押します。
終わるとこの画面が出てきます。
ここまでで Eclipse の環境準備は終わりです。
Rest APIの作成
次はプロジェクトを作成し、Restコントローラとモックサービスを作ります。
①プロジェクトの作成
Eclipse のメニューから「新規」→「その他」を選びます。
「Spring スタータープロジェクト」を作成します。
サービスURLはデフォルトのまま、あとは全部自分の好きに設定します。
わたしは、Maven と Gradle 両方の経験がありますが、Gradle の方が便利だと感じそちらを使います。
Javaは 8 のままでしばらくは開発しようとは思います。
どこかのタイミングで 12に変更するかもしれません。
次へをクリックすると下の画面になります。ここで選択したライブラリが Gradle の設定ファイルに登録されます。
まずSpring Bootのバージョンは最新「2.2.0」にして
Web、Lombok、H2、JDBC、MyBatis、Flywayを選択しました。
職場では jOOQ や JPA が使われてますが、 MyBatis にしました。いまだにこれが一番いい気がして…
Spring Securityも含めたいところですが、きちんと時間をとってやりたいので、別途あとから手動で入れようと思います。
作成した後、xxxApplication.java が最初の起動ファイルになります。
(このファイルを右クリックして実行するとサーバが起動します)
②コントローラ / モックサービスの作成
いま私が考えているシステムではログイン画面下に管理者からのお知らせを表示します。
そのお知らせを取得するAPIを作ります。
そこで今回は下記 3ファイルを Eclipse に追加します。
○DTO
entiry/InformationDto.java
○モックサービス
mockService/MockInformationService.java
○コントローラ
controller/InformationRestController.java
Eclipse 画面の左端パッケージエクスプローラーではこのような構成になります。
まずDTOについてですが、
@Data
は Lombok 用のアノテーションです。
このアノテーションを書くと getter / setter が自動的に作られます。
@AllArgsConstructor
も Lombok 用のアノテーションです。
このアノテーションを書くと その名前の通り、すべての引数を渡すコンストラクタが自動的に作られます。
package com.weekenditlaboratory.entity.dto; import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class InformationDto { private String date; private String information; private String detail; }
次にモックサービスです。
@Service
は Spring のアノテーションです。
これは Spring でいうところのいわゆるサービス(ビジネスロジック)につけるアノテーションです。
今回はモックを作りたくDBに接続せずに固定値を返すようにします。
List<InformationDto>
を返す、#searchAll()
メソッドを追加しました。
package com.weekenditlaboratory.mockService; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Service; import com.weekenditlaboratory.entity.dto.InformationDto; @Service public class MockInformationService { public List<InformationDto> searchAll(){ InformationDto informationDto1 = new InformationDto("2019/3/1","運用停止のお知らせ","メンテナンスのため月末の0:00~2:00まで運用を停止します。"); InformationDto informationDto2 = new InformationDto("2018/2/1","運用停止のお知らせ","メンテナンスのため月末の0:00~2:00まで運用を停止します。"); InformationDto informationDto3 = new InformationDto("2018/1/1","運用開始","運用を開始します。"); List<InformationDto> res = new ArrayList<InformationDto>(); res.add(informationDto1); res.add(informationDto2); res.add(informationDto3); return res; } }
最後にコントローラ
@RequiredArgsConstructor
は lombok のアノテーションで、クラス中で「static final」宣言したオブジェクトのコンストラクタを自動的に作ります。
この場合、Spring が Lombok で作ったコンストラクタに合わせて mockInformationService を DI してくれます。
そして他は Spring のアノテーションです。
@RestController
は Rest 用のアノテーションです。もちろん他の形式のコントローラもあります。例えば Thymeleaf だと @Controller
。
@RequestMapping
アノテーションは http リクエストの URL を指定します。
@CrossOrigin
はクロスドメイン接続を許す設定です。
Angular をng serve で動かした場合クロスドメイン制約にかかり接続できず一時的にクロスドメインを許しました。
※本来はコントローラに書くべきではなく Spring Security の設定ファイルなど1ケ所に書き、さらにローカル環境のみでの設定にすべきですが、今回はまだお試し中なので、アノテーションを直接書き込みました。
@GetMapping
は Rest でいうところの http メソッド の GET が呼ばれた場合に動くコントローラのメソッドを指定しています。
つまり http://example/api/informations が GET で呼ばれた場合には InformationRestController の #getInformations() が動きます。
そしてそのメソッド内でモックサービスが呼ばれ InformationDto のリストが Spring の中で Json に変換されてhttp のレスポンスとして返されます。
package com.weekenditlaboratory.controller; import java.util.List; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.weekenditlaboratory.entity.dto.InformationDto; import com.weekenditlaboratory.mockService.MockInformationService; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @RestController @RequestMapping("api/informations") @CrossOrigin public class InformationRestController { private final MockInformationService mockInformationService; @GetMapping public List<InformationDto> getInformations(){ return mockInformationService.searchAll(); } }
ここまで来たら Spring を起動して Angular とつないでみます。
下記のログイン画面の下、お知らせが今日のAPIを使っている場所です。
とりいそぎ無事繋がりました。
しばらくは Spring側 はモックサービスのみを作り Angular の製造がある程度落ち着いてから、
DBを使った本物のサービスに変えていきたいと思っています。
今日の感想
今日は Spring の記事を書きました。何度も繰り返した手順ですが、こうやってブログに書くとまた新鮮に思えます。
Angular 以外のところに時間をかけてしまいましたが、次回こそは Angular で http 通信をおこなうところを書きたいと思います。
では、お疲れ様でした。
今夜は社内AWSもくもく会 - EC2その1 キーペアとセキュリティグループ
こんにちはふるてつです。
今回も社内AWSもくもく会の内容です。EC2の利用その1になります。
今回のテーマはキーペア(公開鍵・秘密鍵)の作成と、
セキュリティグループの作成です。
わたしの超苦手なところですね~
キーペア(公開鍵・秘密鍵)作成
EC2のインスタンスを作る前に、まずはキーペアを作ります。
まずはEC2のダッシュボードのメニューから「キーペア」をクリックします。
下の画面が表示されます。
そこで「キーペアの作成」ボタンをクリックします。
作成完了と同時にpem形式のファイルをダウンロードします。
このタイミングでしかキーペアのファイルはダウンロードできないので、
無くさないよう気をつけて管理してください。
うーん、なんだかあっけなく作れました。
セキュリティグループの作成
次はセキュリティグループ。
同じくEC2のダッシュボードメニューから「セキュリティグループ」をクリックすると下記の画面が表示されます。
そこで「セキュリティグループの作成」ボタンをクリックする。
下記の画面が表示されるので以下のように入力します。名前と説明は良い感じで書くだけです。
VPCは以前作ったものを選び、「作成」ボタンをクリックする。
セキュリティグループが追加されました。
その後はルールの設定を行います。
インバウンドのタブを開いてSSHの許可を追加します。
これでSSHが通るようになったはずですねぇ。
しかしまだ肝心の EC2 を作っていませんので、いまは試せません。
次回こそは EC2 のインスタンスを作りたいと思います。
感想
今日勉強した内容はもう少し先まであったのですが、キリが悪くてここでいったん区切りました。
EC2 の続きはまた今度書きたいと思います。
まだまだ本の半分も行ってません。先は長いかも。
ではでは
Angular7 + Bootstrap4でWebアプリを作ろう - サービス追加 その1
こんにちはふるてつです。
3月から後輩と二人で社内 Angular もくもく会もはじめました。
これからは AWS と同様に Angular についても、もくもく勉強した内容を書いていきたいと思います。
基本的にはこれまで作ってきたアプリの続きになりますが、作業時間が限られるので若干内容が少なくなるかとは思います。
今回は復習もかねてチュートリアルを参考にサービスを追加しました。
サービス追加
私が個人的に作っているアプリケーションは、下記のようにログイン画面の下にお知らせを表示したいと思っています。
これまではとりあえず Component 内で直接データを作って表示していましたが、今回から Service を追加して Service からデータを取得するように書き換えます。
わたしの環境は app の下に service/information フォルダを作っているので、そこに information(お知らせ)サービスをつくります。
CLIコマンドは下記です。
ng generate service service/information/information
app/service/information 配下にファイルが2つできました。
information.service.spec.ts information.service.ys
VSCodeでみると下記のようになります。
最近「Material Icon Theme」というプラグインをVSCodeに入れました。
画面左側エクスプローラーのフォルダやファイルアイコンが良い感じになっているでしょう。
その他、モック追加
Angularのチュートリアルを見るとヒーローサービスを作るときにモックヒーローを作ってますね。https://angular.jp/tutorial/toh-pt4
同じように インフォメーションのモック mockInformation を作ってみます。
ng generate class mock/mockInformation
固定値を返すだけなので "class" を作成します。
mock-information.spec.ts mock-information.ts
これは固定値を返すだけなのでテスト不要。
そのため mock-information.spec.ts はいったん削除しました。
mock-information.ts の中身はこのような内容です。モックなので固定値です。
import { Information } from '../entity/domain/information';
export const INFORMATIONS: Information[] = [
{ date: '2019/3/1', information: '運用停止のお知らせ', detail: 'メンテナンスのため月末の0:00~2:00まで運用を停止します。' },
{ date: '2018/2/1', information: '運用停止のお知らせ', detail: 'メンテナンスのため月末の0:00~2:00まで運用を停止します。' },
{ date: '2018/1/1', information: '運用開始', detail: '運用を開始します。' }
];
インフォメーションサービスの書き換え
最初にCLIコマンドで作った informationService の内容を書き換えます。
下のように。
Observable でモックインフォメーションを返すようにします。
import { Injectable } from '@angular/core';
// ↓追加
import { Observable, of } from 'rxjs';
import { Information } from 'src/app/entity/domain/information';
import { INFORMATIONS } from 'src/app/mock/mock-information';
// ↑追加
@Injectable({
providedIn: 'root'
})
export class InformationService {
constructor() { }
// ↓追加
getInformations(): Observable {
return of(INFORMATIONS);
}
// ↑追加
}
ログインコンポーネントの書き換え
ログインのコンポーネントも書き換えます。
コンストラクターで informationService をインジェクトして、初期化時に informationService の #getInformations() メソッドを呼び出します。
これもチュートリアル通りです。
import { Component, OnInit } from '@angular/core';
import { Information } from '../../../entity/domain/information';
// ↓追加
import { InformationService } from '../../../service/information/information.service';
// ↑追加
@Component({
selector: 'app-if1001-login',
templateUrl: './if1001-login.component.html',
styleUrls: ['./if1001-login.component.css']
})
export class If1001LoginComponent implements OnInit {
// ↓コンストラクタは書き換え(infomationServiceを DI するように)
constructor(private infomationService: InformationService) { }
// ↑書き換え
// ↓追加
// お知らせ
informations: Information[];
// ↑追加
ngOnInit() {
// ↓追加
this.getInformations();
// ↑追加
}
// ↓追加
getInformations(): void {
this.infomationService.getInformations().subscribe(Informations => this.informations = Informations);
}
// ↑追加
}
これでコンポーネントにサービスを追加できました。
今日の感想
今日は Angular のサービス追加について書きました。
ほぼチュートリアルをまねただけに終わってしまいましたが、しばらくはなれていたので思い出すのにはちょうどよかったと思います。
次回はモックでなく、HTTPで実際に通信してデータを取得するようにサービスを変える予定です。
では、お疲れ様でした。
今夜は社内AWSもくもく会 - CloudFormer(ベータ版)の後日談、初の課金
こんにちはふるてつです。
今回も社内AWSもくもく会の内容です。
前回 CloudFormer をご紹介しましたが、その後 CloudFormer が元でさっそく課金されました。
$4ほどなので大して気にしていませんが、びっくりしました。
まだ12か月の無料期間のはずなので注意して使えば大丈夫と思っていたのですが。
今日はそのお話です。
その1 請求のアラートメールが届く
週末にAWSから請求のアラートメールが届きました。
こんな感じのメールが...
その2 AWSで請求額確認!
AWSにログインして請求額を見る。
あら~$4くらいかかっとる。もっとかな
EC2のインスタンスを確認!
EC2がたしかに上がっとる。
だけど、でも作った覚えがないんだけど…
その3 ああ思い出した。 CloudFormer だ。
思い出しましたよ。 CloudFormer を動かそうとしたときに CloudFormation でEC2インスタンスを作ったのでした。
すっかり忘れてました。うーむ、無料枠(micro)ではない small でEC2が作られていました。
その4 CloudFormationごと削除!
というわけで、スタックごと削除しました。
感想
今日は思わぬ出費をしてしまったお話になってしまいました。
そもそも CloudFormer を試した後にすぐスタックを消せばよかったですねぇ。
自分が設定したアラートメールが見れたことだけは良かったですが…
今日は小ネタでした。ではでは