web-dev-qa-db-ja.com

subscribe Angular 4内で値を返す方法

角度のオブザーバブルは初めてです。サブスクライブメソッド内で値を返したいという問題があります。次のメソッドがあります(getFirebaseData(idForm:string):observable <any[]>):

_getTotalQuestions(idForm:string){
let totalQuestions:number;
this.getFirebaseData(idForm+"/Metadatos")
.subscribe(items => 
  {
    items.map(item => {
      totalQuestions=item.Total;
      console.log(totalQuestions);
    });
  }
);
console.log(totalQuestions);
return totalQuestions;
}
_

最初のconsole.log(totalQuestions) print 4ですが、2番目のconsole.log(totalQuestions) print ndefinedです。サブスクライブは非同期操作であり、そのため2番目のconsole.log(totalQuestions)(「コードを書くために」)は未定義で印刷されることを理解していますが、サブスクライブメソッドの後に変数を返す方法が見つかりません完了しました。さて、サブスクライブをmapに変更すると:

_getTotalQuestions(idForm:string){
let totalQuestions:number;
this.getFirebaseData(idForm+"/Metadatos")
.subscribe(items => 
  {
    items.map(item => {
      totalQuestions=item.Total;
      console.log(totalQuestions);
    });
  }
);
console.log(totalQuestions);
return totalQuestions;
}
_

最初のconsole.log(totalQuestions)は何も出力せず、2番目のconsole.log(totalQuestions)は未定義を出力します。それが起こるので、私には理解できないものです。

私が理解していない概念を明確にしてくれることを願っています。ありがとう!

13
AlejoDev

総質問を直接返すことはできません。そのためには、サブジェクトを使用する必要があります。

getTotalQuestions(idForm:string): Observable<string> {
let totalQuestions:number;
var subject = new Subject<string>();
this.getFirebaseData(idForm+"/Metadatos")
.subscribe(items => {
    items.map(item => {

      totalQuestions=item.Total;
      console.log(totalQuestions);
      subject.next(totalQuestions);
    });
  }
);
  return subject.asObservable();
}

使用法:getTotalQuestion(idForm).subscribe((r)=>console.log(r))

16
Rajani Kanth

Observableは、サブスクライブすると実行され、サブスクリプションから返されるものは常にsetIntervalのようなサブスクリプションオブジェクトです。最初のサンプル:これは非同期呼び出しであるため、2番目のconsole.logは、subcribeが終了するのを待ってから実行します。

getTotalQuestions(idForm:string){
let totalQuestions:number;
this.getFirebaseData(idForm+"/Metadatos")
 .map(items => 
     items.map(item => {
     totalQuestions=item.Total;
     console.log(totalQuestions);
  });
)
}
getTotalQuestion('231').subscribe(console.log)
2
Fan Cheung

実際の例を作成しました 。配列への変換を行うためにサブスクリプションを起動する必要はありません。また、オブジェクトを単一の値に減らす必要はありません。これが私のアプローチです。 あなたのサービス

getTotalQuestions(idForm: string): Observable<any> {
    return this.getFirebaseData(`${idForm}/Metadatos`)
        .pipe(map(items => items
            .map(item => item.Total)
            .reduce((a, b) => a+b), 0));
}

お使いのコンポーネント

this.service.getTotalQuestions('id')
    .subscribe(totalQuestions => console.log(totalQuestions));
0
Luillyfe