私は現在、AngularJS 1. *を過去4年間喜んで使用した後、Angular2とTypeScriptを自分で習得しようとしています。私はそれを嫌っていることを認めなければなりませんが、私の交響詩momentエウレカの瞬間はすぐそこにあると確信しています...とにかく、私はダミーのアプリで、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');
}
}
ここで、コンポーネントでgetUserInfo()
メソッドとgetUserPhotos(myId)
メソッドの両方を実行(またはチェーン)します。 AngularJSではこれは簡単でした。私のコントローラーでは、「運命のピラミッド」を避けるためにこのようなことをするからです...
// 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];
});