web-dev-qa-db-ja.com

TypeScript-オブザーバブル/プロミスが終了するのを待ち、オブザーバブルを返す

私はTypeScriptとRxJSを初めて使用し、別のObservableが終了した後にObservableを返そうとしています。

public myObservable = () : Observable<boolean> => {
    console.log('retrieving the token in DB');
    return Observable.create(observer => {
        setTimeout(() => {
            observer.next(true);
            observer.complete();
        }, 5000);
    });
}

public makeRequest = (): Observable<any> => {
    return this.myObservable().subscribe(
        function (x) {
            console.log('I have the token, now I can make the HTTP call');

            return this.http.get('http://jsonplaceholder.typicode.com/posts/1')
                .map( (responseData) => {
                    return responseData.json();
                })
                .map((item:any) => {
                    return {
                        id: item.id,
                        userId: item.userId,
                        title: item.title,
                        body: item.body
                    };
                });

        },
        function (err) {
            console.error('Error: ' + err);
        },
        function () {
            console.log('Completed');
        });

}

次のエラーを受け取りました:「返された式タイプのサブスクリプションは、タイプObservable<any>に割り当てられません」。

私はここでエラーを完全に理解しています(Observableはストリームのようなものであり、サブスクリプションはそのストリームを「観察する」という事実です)ですが、Observable(またはpromise)は、新しいObservableを返すために終了します。どうやってやるの?

29
Geoffrey D

問題は、Observableを.subscribeで異なる型に変換することです-すべきではありません(observableを返しません)

public makeRequest = (): Observable<any> => {
    return this.myObservable().subscribe(
      ... // this is wrong, we cannot return .subscribe
          // because it consumes observable and returns ISusbcriber
    );
}

オブザーバブルがある場合は、その結果を取得し、.mapを使用して他の何かに変換する必要があります

FlatMap演算子

observableから放出されたアイテムをObservableに変換し、それらからの放出を単一のObservableにフラット化します

public makeRequest = (): Observable<any> => {
    return this.myObservable()
       .flatmap((x) => return this.http
              .get('http://jsonplaceholder.typicode.com/posts/1')
              .map( (responseData) => {
                    return responseData.json();
              })
              ...

ここですべての詳細を確認してください

ANGULAR 2で観測可能なものを活用する

23
Radim Köhler

FlatMap()は機能しますが、使用するパラメーターを渡さないため[param(x)を参照]、このシナリオで使用するのに最適な演算子はforkJoin()です。

この例を参照してください: https://stackoverflow.com/a/38049268/174239

   Observable.forkJoin(
    this.http.get('/app/books.json').map((res:Response) => res.json()),
    this.http.get('/app/movies.json').map((res:Response) => res.json())
).subscribe(
  data => {
    this.books = data[0]
    this.movies = data[1]
  },
  err => console.error(err)
);
14
rbj325

これは私の問題でもあるので、私はいつかこの答えを探しています。今日は答えがあり、共有したいと思います。

コードは次のとおりです。

ngOnInit() {
var idEntidade: number;

this.route.paramMap.subscribe(params => {
  idEntidade = Number(params.get('id'));
});

this.dataService.getEstados().subscribe(data => {
  this.estados = data;
});

var dados = this.dataService.getCliente(idEntidade);

**this.subscription = dados.subscribe(
  (data: Cliente) => { this.entityForm.patchValue(data);},
  null,
  () => { this.completed(); }
  );**
}

そして、サブスクライブが完了すると、完了した機能が実行されます。

completed(){
let idEstado: number = this.entityForm.controls['estadoId'].value;

if (idEstado === null) {
  return;
}

this.dataService.getMunicipiosByEstado(this.entityForm.controls['estadoId'].value)
    .subscribe(data => { this.municipios = data; });
}

お役に立てれば。