web-dev-qa-db-ja.com

observableへのサブスクライブは未定義を返します

そこで、ローカルのJSONファイルからデータを返す簡単なサービスにサブスクライブしようとしています。

サービスを機能させることができたので、関数でログアウトできますが、angular 2コンポーネントでサービスをサブスクライブすると、常に未定義になります。なぜですか?どんな助けも大歓迎です。

APIサービス

export class ApiService {
   public data: any;

   constructor(private _http: Http) {
   }

   getData(): any {
       return this._http.get('api.json').map((response: Response) => { 
       console.log('in response', response.json()); //This logs the Object
       this.data = response.json();
       return this.data;
   })
   .catch(this.handleError);
   }
}

成分

export class AppComponent {
   public data: any
   public informationData;

   constructor(private _api: ApiService) {}

   public ngOnInit(): void {
      console.log(this.getDataFromService()); // This return undefined
   }

   public getDataFromService() {
      this._api.getData().subscribe(response => {
          this.informationData = response;
          return this.informationData;
      });
   }
}
6
Sam Kelham

おそらくいくつかの写真が役立ちますか?

ここの数字は、操作の順序を示しています。

Httpリクエストを送信enter image description here

  1. コンポーネントは初期化され、movieServiceのgetMoviesメソッドを呼び出します。
  2. MovieService getMoviesメソッドはObservableを返します。この時点のデータではありません。
  3. コンポーネントは、返されたObservableでsubscribeを呼び出します。
  4. get要求は、処理のためにサーバーに送信されます。
  5. ngOnInitメソッドが完成しました。

subscribeの後のコードは、データがまだ返されていないため、moviesプロパティにアクセスできません。

Http応答を受信するenter image description here

後のある時点で...

  1. 映画はサービスに返されます。
  2. プロセスが成功した場合、最初のコールバック関数が実行されます。
  3. ローカルムービープロパティは、サービスから返されたムービーに割り当てられます。 moviesプロパティが最終的に設定されるのはここだけです。

手順8の前にmoviesプロパティにアクセスしようとすると、エラーが発生します。

ここで値にアクセスできますか? NOenter image description here

修正するには:enter image description here

31
DeborahK

同期機能と非同期機能の間に問題があります。あなたの問題は:getDateFromServiceは同期的で、中のコンテンツは非同期です。したがって、ngOnInit関数がgetDataFromServiceを呼び出すとき、コードは非同期タスクを待機しません。 getDataFromServiceはオブザーバーを返すか、APIのリターンを実装する必要があります(選択する必要があります)。

public ngOnInit(): void {
  console.log(this.getDataFromService().subscribe(data => console.log(data)); // This return undefined
}

public getDataFromService() {
  return this._api.getData();
}
0
Antoine Clavijo
objResponse;
this.service.getData().subscribe((result: any)=> { 
this.objResponse=result;
}

何かを返す必要はありません

0
mehul

NgOnInit()メソッドでログを記録する代わりに

 public ngOnInit(): void {
      console.log(this.getDataFromService()); // This return undefined    }

subscribe()メソッド内に次のようにログインします

export class AppComponent {
  public data: any
  public informationData;

  constructor(private _api: ApiService) {}

  public ngOnInit(): void {
    this.getDataFromService(); //don't log here, logging here will return undefined
  }

  public getDataFromService() {
    this._api.getData().subscribe(response => {
      this.informationData = response;
      console.log(this.informationData); //log here, like this
      return this.informationData;
    });
  }
}
0
dips