画面遷移のないシングルページのWebアプリケーションでは、Ajaxが使えないと話にならないですよね。
Angular2ではHttpクライアントが機能として含まれています。
今回はAngular2でのHttpクライアントでデータを取得する方法を紹介します。
Httpクライアント
これから全部で3つのコードを紹介します。
今回例で使うソースコードは公式リファレンスで紹介されているものです。
Ajaxで取得したデータをリストで表示します。
app/toh.component.ts
import { Component } from '@angular/core';
import { HTTP_PROVIDERS } from '@angular/http';
import { HeroListComponent } from './hero-list.component';
import { HeroService } from './hero.service';
@Component({
selector: 'my-toh',
template: `
<h1>Tour of Heroes</h1>
<hero-list></hero-list>
`,
directives: [HeroListComponent],
providers: [
HTTP_PROVIDERS,
HeroService,
]
})
export class TohComponent { }
ではまずはじめに、ベースとなるリスト表示のコンポーネントを定義します。
なんかいっぱい書いてあって、よくわからないですよねw
大丈夫です、ひとつずつ見ていきましょう。
まず、 HTTP_PROVIDERS
をimportします。これは、Httpクライアントを使うための処理が定義されています。
@Component
の providers
プロパティに指定しておきます。
実際にHttpクライアントで通信する機能は、HeroService
に任せます。これも providers
に追加します。
これは、Angular2のDependency Injection(依存的注入) という機能で外部化しています。
(Dependency Injectionについては後日詳しく紹介します。ここでは、処理を使いまわせる仕組みと考えていれば大丈夫です。)
Angular2ではコンポーネント志向の設計なので、処理を独立させることが簡単にできます。
コードを見ると、すっきりしていてストレスフリーですね。
app/toh/hero-list.component.ts (class)
次に、先ほど定義した TohComponent
のリスト部分を定義します。
TohComponent内の <hero-list></hero-list>
の部分がこれにあたります。
import { Component, OnInit } from '@angular/core';
import { Hero} from './hero';
import { HeroService } from './hero.service';
@Component({
selector: 'hero-list',
template: `
<h1>Tour of Heroes ()</h1>
<h3>Heroes:</h3>
<ul>
<li *ngFor="let hero of heroes">
{{hero.name}}
</li>
</ul>
New hero name:
<input #newHeroName />
<button (click)="addHero(newHeroName.value); newHeroName.value=''">
Add Hero
</button>
<div class="error" *ngIf="errorMessage">{{errorMessage}}</div>
`
...
})
export class HeroListComponent implements OnInit {
constructor (private heroService: HeroService) {}
errorMessage: string;
heroes: Hero[];
ngOnInit() { this.getHeroes(); }
getHeroes() {
this.heroService.getHeroes()
.subscribe(
heroes => this.heroes = heroes,
error => this.errorMessage = <any>error
);
}
}
初期化のタイミングで、getHeroes
メソッドで heroService.getHeroes()
を実行して、Http通信をしています。
ngOnInit
についてはAngular2のLifecycle Hooksを理解するを参考にしてください。
getHeroes
メソッド内の subscribe()
というのはRxJSの機能です。今はHttpの処理が終わった後に、
実行されるものだと思っていれば問題ありません。
Httpでデータを取得した後は、HeroListComponent自身の heroes
メンバーに保存しています。
データが保存されれば、<li *ngFor="let hero of heroes"></li>
のheroes
に自動的に反映されて、リストが生成されます。
app/toh/hero.service.ts
最後にHttpサービス本体です。
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Hero } from './hero';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class HeroService {
constructor (private http: Http) {}
private heroesUrl = 'app/heroes'; // URL to web api
getHeroes (): Observable<Hero[]> {
return this.http.get(this.heroesUrl)
.map(this.extractData)
.catch(this.handleError);
}
// レスポンスデータの整形処理
private extractData(res: Response) {
if (res.status < 200 || res.status >= 300) {
throw new Error('Bad response status: ' + res.status);
}
let body = res.json();
return body.data || { };
}
// エラー処理
private handleError (error: any) {
// In a real world app, we might send the error to remote logging infrastructure
let errMsg = error.message || 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
はじめに、@Injectable
で他のコンポーネントからimportできるように宣言しています。
Httpを使うためには、import { Http }
でHttpオブジェクトをimportする必要があります。
そして、constructorの引数で、Httpオブジェクトをクラスのhttpメンバーに追加します。
※TypeScriptでは、constructorの引数でprivate
や public
などのキーワードをつけると、そのクラスのメンバーに追加されます。
ここでは、getHeroes
メソッドに注目しましょう。
http.get()
で get
メソッドでの通信を行います。第1引数にはURLを指定します。
返り値はRxJSのObservableというデータになりますが、今は理解できなくても大丈夫です。
Observableのmap
メソッドでAjaxでのレスポンスをチェック、json化しています。
RxJSは理解が難しいので、ここではレスポンスデータを整形していると認識できればOKです。
catch()
ではエラーハンドリングをしています。
レスポンスデータをコンポーネントで受け取る
HeroListComponent
で getHeroes
メソッドがあったのを覚えていますか?
getHeroes() {
this.heroService.getHeroes()
.subscribe(
heroes => this.heroes = heroes,
error => this.errorMessage = <any>error
);
}
この中の subscribe
メソッドの第1引数に渡す関数の内で、レスポンスデータにアクセス出来ます。
データがコンポーネントに保存されると、自動的にリスト表示されるという仕組みです。
複雑だけど、まずは使って慣れよう
ファイルが複数に分かれていたり、
いろんな技術が一気に出てきてかなり複雑ですが、
要点を抑えて慣れてしまえばこっちのもの。
Httpクライアントはとても頻繁に使うので、ぜひとも理解してもらいたいです。
今回は get
メソッドの紹介でしたが、今後 post
メソッドなども紹介します。