2017-11-27 22 views
2

私はAngular 4アプリを書いています。これには2つのリストが含まれます。最初のリストの要素をクリックすると、結果は新しいビューの2番目のリスト(外部キーを使用)のサブセットになります。私は私のサービス内の関数でid(外部キー)によるフィルタリングを行います。私のコンポーネントでは、私はちょうど 'undefined'を受け取る。 私は、私のサービスでObservableを使用しており、サブセットリストの新しいビューが表示されているときにデータが準備できていないと考えています。私の目標を達成するためにこれを別の方法でどうやって行うことができますか?角度 - 観測可能なデータが準備できていませんか?

マット・テーブルのセルでクリックイベントを経て、私のサービスでメソッドを呼び出す:私のcomponent.ts

の私 service.ts

getItemsByID(id: number): Observable<Item[]> { 
    return this.http.get('/api/Item').map((response) => { 
     console.log(id); //shows correct item id 
     console.log(this.items.filter(iteration => item.item_id === id)); // shows correct array of subset list 
     return this.items.filter(item=> item.item_id === id); 
    }); 
    } 

方法で

方法

getItem(): void { 
    const id = +this.route.snapshot.paramMap.get('id'); 
    this.itemService.getItemsByID(id) 
     .subscribe(response => this.items = response);  
    console.log(this.items); // shows 'undefined' 
} 

私のコードからあなたを示すには他に何が必要ですか?

完全なログ:

undefined

4

Array [ {…}, {…}, {…}, {…} ]

どうもありがとう!

+0

は、内部にconsole.log()**を入れ**購読に渡されたコールバック()。 httpは非同期です。それがObservableを返す理由です。それが応答が利用可能になるまでブロックされている場合、それはあなたが観察可能で気にならないでしょう。応答を直接返します。トースターに入れた直後にトーストを食べることはできません。トーストが準備ができていることをトースタが通知すると、それを食べる。 –

+0

問題のトラブルシューティングに役立つ詳細を追加してください。 Angularによって提供される2つのHttpサービスがあります。どのモジュールを使用していますか?あなたの答えは –

答えて

2

HttpClienthttpとし、responseにはリストが、.json() is not a functionには書かれているとします。

サービスthis.itemsプロパティを削除するとよいでしょう。おそらく、あなたはこのプロパティがサービスとコンポーネントの両方にthis.itemsとして存在すると思いますか? thisは別々のオブジェクトを指します。サービスはこのような状態を維持しなければならないが、方法だけを維持しなければならない場合には最高のものになるだろう。

getItemsByID(id: number): Observable<Item[]> { 
 
    return this.http.get<Item[]>('/api/Item').map((items) => { 
 
    console.log(id); //shows correct item id 
 
    const filtered = items.filter(item => item.item_id === id); 
 
    console.log(filtered); // shows correct array of subset list 
 
    return filtered; 
 
    }); 
 
}

は、その後のサービスを消費:

getItem(): void { 
 
    const id = +this.route.snapshot.paramMap.get('id'); 
 
    this.itemService.getItemsByID(id) 
 
    .subscribe(items => { 
 
     this.items = items; 
 
     console.log(items); 
 
    ); 
 
    }); 
 
}

+0

助けてくれてありがとう!ありがとう!今私は理解しようとすると、私は多くのことを学ぶべきだと思う。ありがとう! – dafna

1

この応答をサービス配列変数内に保存する理由はわかりませんが、サービスからマップされたデータを返すだけで済みます。

getItemsByID(id: number): Observable<Item[]> { 
    return this.http.get('/api/Item') 
     .map((response: Response) => { 
     // return json object from http response 
     let mapped = response.json(); 
     // given that mapped is an array of itens 
     return mapped.filter(item => item.item_id === id); 
    }); 
} 

また、お使いのコンソールは購読方法外です。非同期で、応答が終了するまで待つ必要があります。

getItem(): void { 
    const id = +this.route.snapshot.paramMap.get('id'); 
    this.itemService.getItemsByID(id) 
     .subscribe((response) => { 
      this.items = response; 
      console.log(this.items); 
     }); 
} 
+0

ありがとう。最初のメソッドへの最初の情報:応答のためのプロパティ項目は存在しません。 – dafna

+0

@dafna cool!あなたが同じ道を荒くすれば、あなたは望みの結果を達成することができます。それは、サーバーからの応答が応答内にあるitensです例です。 – Fals

+0

このエラーが発生します。私が方法1、行4 '応答'を 'これ'に変更した場合、私はまた、未定義の問題を取得します。なぜなのかご存知ですか? – dafna

0

観測、彼らは初期値(BehaviorSubject.startsWith())を持っているか、同期している場合を除き、ちょうど購読するコールの後準備ではありません。 Httpサービスは非同期なので、コンシューマーを適応させる必要があります。時間がたつにつれて、すべてのオブザーバブルが非同期であるかのように構造化するほうがよいことがわかります。 getItem()がvoidのあなたの考える

、一つの選択肢は、加入者に処理を移動している:

getItem(): void { 
 
    const id = +this.route.snapshot.paramMap.get('id'); 
 
    return this.itemService.getItemsByID(id); 
 
}
Access properties: 
 
{{ (getItem() | async).someProperty }} 
 

 
Pass to inner components: 
 
<cmp [item]="item | async"></cmp>
:角の

getItem(): void { 
 
    const id = +this.route.snapshot.paramMap.get('id'); 
 
    this.itemService.getItemsByID(id) 
 
    .subscribe(response => { 
 
     this.items = response; 
 
     // process it here, for instance calling ChangeDetectorRef#markForChanges() 
 
     // to make Angular update the component view 
 
     // see https://stackoverflow.com/a/47463896/592792 
 
    }); 
 
}

もう、かなりクールな機能がasyncパイプを使用しています

この場合、Observableを渡して表示します。 asyncは必要な場所に値を展開して渡します。また、observableをコンポーネントプロパティに格納して、一度だけ作成して登録することもできます。

+0

:-(それは大した事ないだろうと思った。しかし、あなたの答えに感謝! – dafna

+0

二 '@dafnaこれは非常に重要な概念ですが、今は使用する必要はありませんが、これを理解することをお勧めします(非同期パイプ、OnPushの変更検出、観測対象の構成) –

関連する問題