2017-12-09 14 views
1

目的はIDのコレクションを反復し、各IDに対してHTTPコールを行うことです。各IDについて、Observableを返すget()メソッドでサービスを使用しています。 get()メソッドが呼び出されるたびに、Observableを返すことに同意し、結果を配列にプッシュしようとすると、最終的に新しい操作のために別のメソッドに渡されます。角2/4&RxJS - forEach内のサブスクリプション - すべてのオブザーバブルが完了するまでフロー制御を続行しないようにする

関連サービス方法:

public get(departmentId: number): Observable<IDepartmentModel> { 
    return super.get<IDepartmentModel>(departmentId); 
} 

注:スーパークラスは十分にテストされ、正しく動作していることが確認された角度のHttp、活用しています。 ノートforEachの内、数回呼び出されていますdepartmentService.get()の呼び出し:ロジックの問題は...ここ

関連するコンポーネントのメソッドではありません。

setInitialDepartmentsAssignedGridData(): void { 
    this.settingsForDropdownSelectedCompanyId = this.userForm.get('defaultCompany').get('defaultCompanyId').value; 

    let departments: IDepartmentModel[] = []; 

    this.userService.user.getValue() //confirmed: valid user is being pulled back from the userService (logic is fine here..) 
     .userCompanies.find(comp => comp.companyId === this.settingsForDropdownSelectedCompanyId) // getting a valid match here (logic is fine here..) 
     .departmentIds.forEach(deptId => this.departmentService.get(deptId).first().subscribe(dept => { // getting a valid department back here (logic is fine here...) 
      departments.push(dept); // HERE LIES THE PROBLEM 
    })); 

    this.setDepartmentsAssignedRowData(departments); 
} 

setDepartmentsAssignedRowData(departments: IDepartmentModel[]): void { 
    console.log('setDeptAssignedRowData called'); // confirmed: method is getting called... 
    console.log(departments); // confirmed: fully-composed collection of departments logged to the console... 

    departments.forEach(dept => { 
     console.log(dept); 
    }); // Y U NO WORK!? 

    departments.map((department) => { 
     console.log(department); // Y U NO WORK? 
     this.departmentAssignedRowData.push({ 
      departmentId: department.id, 
      departmentName: department.name 
     }); 
    }); 

    this.departmentAssignedGridOptions.api.setRowData(this.departmentAssignedRowData); 
} 

問題は、どのようなコンソールにログインなってきすると、完全に構成部門オブジェクトの配列ですが、それは「そこ」TRULYない、です。 setDepartmentsAssignedRowDataに渡されるものは空の配列です。

何が起きているかは、departments配列が2番目のメソッドに渡される前に非同期操作が完了していないことです。私がオンラインで読んだことの中には、forkJoinを使用すると言われていますが、この文脈でどのように見えるのか分かりません。私はまた、concatMapがうまくいくかもしれないと読んだが、この文脈で、私はその仕事をどうするかわからない...

この文脈では、構成された部門アレイは本当にを渡す準備ができていますか?

ありがとうございました。助けが大変ありがとう!あなたが正しい

答えて

1

は、あなたが並列にしたいHTTPリクエスト観測の配列になります

let observableArray = this.userService.user.getValue() 
    .userCompanies.find(comp => comp.companyId === this.settingsForDropdownSelectedCompanyId) 
    .departmentIds.map(deptId => this.departmentService.get(deptId)) // map is building out an array of observables 

このforkJoinを必要としています。今度はこの配列をforkJoinに渡すことができます。

Observable.forkJoin(...observableArray) 

forkJoinの戻り値は、observableArrayの結果の配列になります。 observableArrayでの観測がすべて完了するまでforkJoinが(そうhttpリクエストのすべてが終了したとき)シーケンス内の次のオペレータに

を放出しないように完全にコードが

let observableArray = this.userService.user.getValue() 
    .userCompanies.find(comp => comp.companyId === this.settingsForDropdownSelectedCompanyId) 
    .departmentIds.map(deptId => this.departmentService.get(deptId)); 

Observable.forkJoin(...observableArray).subscribe(res => { 
    // res = [resId0, resId1, resId2, ..., resIdX]; 
}); 

になります

結果を別の演算子に渡すことについて述べました。その演算子がデータ配列(forkJoin)を渡す別のhttp要求である場合は、flatMap演算子を使用できます。

Observable.forkJoin(...observableArray) 
    .flatMap(res => { 
     return this.otherApi(res); 
    }) 
    .subscribe(res => { 
     // res is the result of the otherApi call 
    }); 

flatMapあなたのAPIリクエストをまとめてチェーンします。だから、完全に何が起こっているのか、平行

  • 一度完了し、実行して第2のAPIでの観測の

    1. 実行アレイ(otherApi
  • +0

    恐ろしい、私はこの試み与えるだろう。ありがとうございました! 1つの質問:forkしないでください。複数のパラメータが必要ですか?私はobservableArrayとObservable.forkJoinには何も渡しませんでしたか? –

    +0

    @SteveBoniface forkJoinは 'selector'パラメータもとります。これは結果を変更する関数です。しかし、これはオプションであり、この場合は必要ありません。それは組織的なものです。あなたは次の演算子で同じ変更を行うことができます – LLai

    +1

    ああ、確かに。私はこの文脈のためにそれを必要としません。私はあなたの提案を試みました(完成したソリューションを見るために私の最初の投稿を編集するでしょう。)あなたの洞察を十分に感謝することはできません。名誉!ありがとうございました –

    関連する問題