2016-01-07 21 views
8

私はAngular 2のhttp GETを試して、HackerNewsのトップ記事のリストを取得しています。その後、ネストされた観察可能な部分でそれぞれの詳細を取得します。Nested Observable in Angular 2

私は、ループして自分のHTMLにデータを表示しようとするとこのエラーが発生します。

が異なるサポートするオブジェクトの[オブジェクトのオブジェクト] '

Cannot find a differ supporting object '[object Object]'

を見つけることができません。また、私が推測していますことは、任意のポインタにこれを行うには良い方法でなければなりませんか?私はそれが巣観察可能なXHR呼び出しに良い習慣だとは思わない...しかし、私はそれについての専門家ではないし、あなたが得た理由を伝えることはできません

getTopPost() { 
    this.http.get('https://hacker-news.firebaseio.com/v0/topstories.json') 
     .map(res => res.json()) 
     .subscribe(
     data => { 
        data.map(function(postId){ 
          let storyUrl = "https://hacker-news.firebaseio.com/v0/item/"+ postId +".json"; 
          that.http.get(storyUrl) 
           .map(res => res.json()) 
           .subscribe(data => that.hnData = data, 
              err => that.logError(err), 
              () => console.log(that.hnData)); 

         }); 

       }, 
     err => this.logError(err); 
    ); 

    } 

HTML

<ion-item *ngFor="#item of hnData"> 
     {{item.title}} 
</ion-item> 

答えて

5

この例外(おそらく約that var ..)。

しかし、私はあなたを表示するために異なるアプローチを持っています。その後、

最初のコンポーネント<top-stories>ロードIDリストとそれぞれのために他人のコンポーネント<top-story>を生成します。

@Component({ 
    selector: 'top-stories', 
    providers: [], 
    template: ' 
    <div> 
     <h2>Hacker news top stories:</h2> 
     <ul> 
     <li top-story *ngFor="#story; #i = index of list | async" [num]="i+1" [id]="story"></li> 
     </ul> 
    </div> 
    ', 
    directives: [TopStory] 
}) 
export class TopStories { 
    list: Observable<Array<number>>; 

    constructor(private http: Http) { 
    this.list = this.http.get('https://hacker-news.firebaseio.com/v0/topstories.json') 
    .map(res => res.json()) 
    .map(list => list.slice(0, 30)); 
    } 
} 

コンポーネント<top-story>負荷自体は、詳細を投稿しますそれを表示する:

@Component({ 
    selector: '[top-story]', 
    providers: [], 
    template: ` 
    <div> 
     <a *ngIf="item" [href]="item?.url">{{ num + ': ' + item?.title }}</a> 
     <span *ngIf="!item">loading...</span> 
    </div> 
    `, 
    directives: [] 
}) 
export class TopStory implements OnInit, OnDestroy { 
    @Input() num: Number; 
    @Input() id: Number; 

    sub: any; 
    item: object; 

    constructor(private http: Http) {} 

    ngOnInit() { 
    this.sub = this.http.get('https://hacker-news.firebaseio.com/v0/item/' + this.id + '.json') 
    .map(res => res.json()) 
    .subscribe(item => this.item = item); 
    } 

    ngOnDestroy() { 
    this.sub.unsubscribe(); 
    } 
} 

このプランナーで再生することができます: http://plnkr.co/edit/BRMlyD?p=preview

+0

が、なぜそれらを入れ子にすることをお勧めではないでしょうか?私は問題を抱えているので、私はそれを約束するようなものにしようとしている(最初の呼び出しを解決してから2番目のことをする)が、別のスコープにあるような未定義のパラメータがある。 – mautrok

+0

私は観測可能なxhr呼び出しをネストするのは悪いとは本当に思いませんが、悪い点はサブスクリプションをネストすることです(他の観測可能なサブスクリプション内のオブザーバブルにサブスクライブする)ことです。あなたは 'flatMap'、' concatMap'、..のような演算子を使い、それを一度だけ購読する必要があります。 – bertrandg

16

私はあなたがこのようなより多くのRxっぽい方法でそれを書き換えることができると思います。

getTopPost() { 
    return http.get('https://hacker-news.firebaseio.com/v0/topstories.json') 
    .map(res => res.json()) 
    .mergeMap(list => Observable.fromArray(list)) 
    .mergeMap(postId => http.get("https://hacker-news.firebaseio.com/v0/item/"+ postId +".json")) 
    .map(res => res.json()) 
} 
関連する問題