使用TypeScript从Angular2的http数据链接RxJS Observable
我目前正在尝试自学Angular2和TypeScript,在过去的4年中与AngularJS 1. *愉快地合作。 我不得不承认,我讨厌它,但是我确定我的灵感即将到来…无论如何,我已经在我的虚拟应用程序中写了一个服务,它将从我写的服务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... });
现在我已经尝试在组件中做类似的事情(replace.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; });
这样,一旦收到第一个请求,就会执行第二个请求。 当您想要使用前一个请求(上一个事件)的结果执行另一个请求时, flatMap
运算符特别有用。 不要忘记导入操作员才能使用它:
import 'rxjs/add/operator/mergeMap';
这个答案可以给你更多的细节:
- Angular 2使用TypeScript错误的HTTP GET http.get(…)。map不是[null]中的函数
如果你只想使用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]; });