[解決済み] Angular2のhttpデータからRxJS ObservablesをTypeScriptで連鎖させる。
質問
私は現在、Angular2とTypeScriptを独学で勉強しようとしています。とにかく、私はJSONを提供する私が書いた偽のバックエンドからhttpデータを取得する私のダミーアプリのサービスを書きました。
import {Injectable} from 'angular2/core';
import {Http, Headers, Response} from 'angular2/http';
import {Observable} from 'rxjs';
@Injectable()
export class UserData {
constructor(public http: Http) {
}
getUserStatus(): any {
var headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.get('/restservice/userstatus', {headers: headers})
.map((data: any) => data.json())
.catch(this.handleError);
}
getUserInfo(): any {
var headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.get('/restservice/profile/info', {headers: headers})
.map((data: any) => data.json())
.catch(this.handleError);
}
getUserPhotos(myId): any {
var headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.get(`restservice/profile/pictures/overview/${ myId }`, {headers: headers})
.map((data: any) => data.json())
.catch(this.handleError);
}
private handleError(error: Response) {
// just logging to the console for now...
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
今度はComponentの中で
getUserInfo()
と
getUserPhotos(myId)
メソッドを使用します。AngularJSでは、コントローラで次のようなことをして、"Pyramid of doom"を避けるので簡単でした...。
// Good old AngularJS 1.*
UserData.getUserInfo().then(function(resp) {
return UserData.getUserPhotos(resp.UserId);
}).then(function (resp) {
// do more stuff...
});
さて、私のコンポーネントで同じようなことをやってみました。
.then
を
.subscribe
を追加したのですが、エラーコンソールが狂ってしまいました。
@Component({
selector: 'profile',
template: require('app/components/profile/profile.html'),
providers: [],
directives: [],
pipes: []
})
export class Profile implements OnInit {
userPhotos: any;
userInfo: any;
// UserData is my service
constructor(private userData: UserData) {
}
ngOnInit() {
// I need to pass my own ID here...
this.userData.getUserPhotos('123456') // ToDo: Get this from parent or UserData Service
.subscribe(
(data) => {
this.userPhotos = data;
}
).getUserInfo().subscribe(
(data) => {
this.userInfo = data;
});
}
}
私は明らかに何か間違ったことをしています...どのように私はObservablesとRxJSに最適でしょうか?もし私が愚かな質問をしているのなら申し訳ありません。また、httpヘッダを宣言するときに、私の関数でコードが繰り返されていることに気づきました...
どのように解決するのですか?
あなたのユースケースの場合、私は
flatMap
演算子が必要だと思います。
this.userData.getUserPhotos('123456').flatMap(data => {
this.userPhotos = data;
return this.userData.getUserInfo();
}).subscribe(data => {
this.userInfo = data;
});
この方法では、最初のリクエストを受信したら、2番目のリクエストを実行することになります。このとき
flatMap
演算子は、前のリクエストの結果 (前のイベント) を使って別のリクエストを実行したい場合に特に有用です。この演算子を使えるようにするために、インポートすることを忘れないでください。
import 'rxjs/add/operator/flatMap';
この回答で詳細がわかるかもしれません。
のみを使用したい場合は
subscribe
メソッドのみを使用したい場合は、このようなものを使用します。
this.userData.getUserPhotos('123456')
.subscribe(
(data) => {
this.userPhotos = data;
this.userData.getUserInfo().subscribe(
(data) => {
this.userInfo = data;
});
});
最後に、もし両方のリクエストを並行して実行し、すべての結果が出たときに通知を受けたいのであれば、以下のように
Observable.forkJoin
を使うことを検討すべきです (そのためには
import 'rxjs/add/observable/forkJoin'
):
Observable.forkJoin([
this.userData.getUserPhotos(),
this.userData.getUserInfo()]).subscribe(t=> {
var firstResult = t[0];
var secondResult = t[1];
});
関連
-
[解決済み] Angular/RxJS `Subscription` からいつ退会すればいいのか?
-
[解決済み] Angular HTTP GET with TypeScript エラー http.get(...).map is not a function in [null].
-
[解決済み] TypeScriptで Object.keys return string[].
-
[解決済み] TypeScriptの予約語 "type "とは何ですか?
-
[解決済み] Typescriptでインターフェースやクラスを使用する場合 [重複].
-
[解決済み] グローバルスコープの拡張は、外部モジュールまたはアンビエントモジュール宣言にのみ直接ネストすることができます(2669)
-
[解決済み] タイプスクリプト。カスタムタイプに対する typeof のチェック
-
[解決済み] ngForとAsync Pipe Angular 2でObservableオブジェクトから配列を利用する。
-
[解決済み] TypeScript Genericsに複数の型制約を指定することは可能か?
-
[解決済み] typescriptで非推奨のマークを付けることは可能ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Angular HTTP GET with TypeScript エラー http.get(...).map is not a function in [null].
-
[解決済み] Angular 2でアプリ起動時にサービスを実行する方法
-
[解決済み] 文字列ユニオンから文字列配列へ
-
[解決済み] tsconfig.jsonのtargetは何のためにあるのですか?
-
[解決済み] タイプスクリプト。カスタムタイプに対する typeof のチェック
-
[解決済み] typescriptのインターフェイスを別ファイルで宣言しインポートする方法
-
[解決済み] TypeScriptをminifiedコードにコンパイルすることは可能ですか?
-
[解決済み] エラー Typescript Feature 1.5。現在の言語レベルは1.4です。
-
[解決済み] TypeScript Genericsに複数の型制約を指定することは可能か?
-
[解決済み] TypeScript Mapファイルとは?