2016-06-14 9 views
1

私はAng2を学んでいます。私はヒーローチュートリアルをうまく使いました。練習するために、メインページにリンクを追加して新しいコンポーネントを入手しました。ラジオステーションのリストを含むjsonファイルがあります。以下は私のサービス、およびコンポーネントです:Angular 2 httpサービス

import { Radio } from '../models/radio'; 

import { Injectable } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 
import 'rxjs/Rx'; 

@Injectable() 
export /** 
* RadioService 
*/ 
    class RadioService { 
    radios: Radio[] = []; 
    len: Number = 0; 
    http: Http; 
    constructor(http: Http) { 
     this.http = http; 
    } 
    getRadios() { 
     console.log('Radios Service is being called'); 
     this.http.get('app/mock/FranceRadioJSON.json') 
      .map((res: Response) => res.json()) 
      .subscribe((rad: Radio[]) => {  // Succes 
       console.log('Radios Service Success'); 
       this.radios = rad; 
       this.len = rad.length; 
      } 

      , err => {// Failure 
       console.log('Radio Services Failure'); 
       console.error(err); 
      } 

      , // complete 
      () => { 
       console.log('Get Radios Complete'); 
       console.log('Records NB: ' + this.len); 
       console.log('radios nb: ' + this.radios.length) 
      } 
      ) 
      ; 
     return this.radios; 

    } 

とコンポーネントは次のとおりです。

import { Component, OnInit } from '@angular/core'; 
import { RouteParams } from '@angular/router-deprecated'; 
import { Radio } from '../../models/radio'; 
import { RadioService } from '../../services/radio.service'; 

@Component({ 
    selector: 'radio' 
    , templateUrl: 'app/html/radio.component.html' 
    , providers: [RadioService] 
}) 
export /** 
* RadioComponent 
*/ 
    class RadioComponent { 
    radios: Radio[] = []; 
    constructor(
     private radioservice: RadioService) { 
    } 
    getRadios() { 
     this.radios = this.radioservice.getRadios(); 
     console.log('radio component NB: ' + this.radios.length); 
    } 
    ngOnInit() { 
     this.getRadios() 


    } 
} 

問題は、サービスの呼び出しが最初に来ているし、何のラジオがサービスである場合はしばらくリターンではありません私はそれが成功し、JSONファイルからすべてのレコードを取得することがわかります。どんな助けでも大歓迎です。

答えて

3

あなたは(あなたがPromiseObservableを使用する場合である)非同期呼び出しからのデータをこのように得ることができません。 Httpが返され、Observableが返されます。 subscribe()が必要で、コールバックでsubscribe(...)に渡すと、データが取得され、ローカルプロパティに割り当てることができます。あなたはこの問題を解決する方法を

そして例:

getRadiosでは、subscribe()を呼び出し、代わりにmap()を使用しないでください。 map()は、発信者がデータを取得できるようにObservableを返します。 subscribe()Subscriptionを返し、が応答データを取得できない場合は、サブスクリプションをキャンセルすることができます(これは便利な場合もありますが、現在はそうではありません;-))。

getRadios() { 
    console.log('Radios Service is being called'); 
    return this.http.get('app/mock/FranceRadioJSON.json') 
     .map((res: Response) => res.json()) 
     .map((rad: Radio[]) => {  // Succes 
      console.log('Radios Service Success'); 
      this.radios = rad; 
      this.len = rad.length; 
     }); 
} 

ここではデータを取得したいので、getRadiosに登録します。購読すると、map()の電話番号getRadiosが実行されます。 subscribe()Observableが実際にその作業を行います:

getRadios() { 
    this.radios = this.radioservice.getRadios() 
     .subscribe((radios) => { 
      this.radios = radios; 
     } , err => {// Failure 
      console.log('Radio Services Failure'); 
      console.error(err); 
     } , // complete 
     () => { 
      console.log('Get Radios Complete'); 
      console.log('Records NB: ' + this.len); 
      console.log('radios nb: ' + this.radios.length) 
     }); 

    // executed before the HTTP get call to the server 
    // console.log('radio component NB: ' + this.radios.length); 
} 

データをすぐにしか返されませんのでsubscribe(...)に渡されたコールバックが実行されたときradiosがまだあるときに

<div>{{radios.xxx}}</div> 

のようなバインディングのエラーを取得することができますnull Angular2はすでにテンプレート内のバインディングを解決します。エラーを回避するには、radiosnullている間

<div>{{radios?.xxx}}</div> 

Angular2がアクセス.xxxにしようとしない安全なナビゲーション(エルビス)演算子を使用することができます。

+1

ありがとうございました。私はプロセスがはるかに良く見えます。 –

+0

サービスが強制的にラジオ[]を返すようにすることができますか、またはコンポーネントのレスポンスを変換する必要がありますか? –

+0

あなたは 'Radio'クラス(またはインターフェース)を提供していませんでした。完全な情報なしで伝えるのは難しい。 http://stackoverflow.com/questions/22885995/how-do-i-initialize-a-typescript-object-with-a-json-objectがあなたの探しているものかもしれません。 –

1

問題は、あなたのサービス内からあなたの監視対象に登録しているということです。あなたのサービスは、Observableを返してから、あなたのコンポーネントからSubscribeに返されます。

だからあなたのサービスは次のようになります。

getRadios() : Observable<Radio[]> { 
    return this.http.get('app/mock/FranceRadioJSON.json') 
        .map((res: Response) => <Radio[]>res.json()) 
} 

そして、あなたのコンポーネント:

getRadios() { 
    this.radios = this.radioservice.getRadios().subscribe(
     r => { 
      this.radios = r; 
     } 
     ... 
    ); 
} 
+0

Observableを含めるには、どのモジュールをインポートする必要がありますか?私は取得しています名前 'Observable'を見つけることができません –

+1

'rxjs/Observable'から 'import {Observable}; –

+0

Merci Agha Mortez –