0

I have following setup:

 let result = service.getResults(); result.data.forEach((row:any) => { this.myService .getObject(row.id) .subscribe((object:any) => { //... }) ); } 

I want do do something, after all the subscriptions of getObject(row.id) have finished. I know there's the add() function but it will do this for every Subscription. Coming from Promises I would have stored every Promise and then in an array and just called Promise.all().

5
  • An observable is never finished. What you can do, will be to get the next value of each observable. But if you are sur that it's an ponctual request, you can convert your Observable as a promise .toPromise() and then you know how to deal with it Commented Mar 13, 2019 at 11:55
  • @Wandrille An observable is never finished if you consider finished to be completed, then your statement is wrong. Commented Mar 13, 2019 at 12:00
  • @Wandrille An observable is finished with complete() method of the observer. For example, HTTP requests returns observable and the observable is finished once its subscription is fired. Commented Mar 13, 2019 at 12:05
  • @Jota.Toledo you're right Commented Mar 13, 2019 at 12:05
  • @Harun Yılmaz Thanks for the info. Commented Mar 13, 2019 at 12:08

2 Answers 2

4

I want do do something, after all the subscriptions of getObject(row.id) have finished.

Better to use forkJoin for your example. From official docs:

forkJoin will wait for all passed Observables to complete and then it will emit an array with last values from corresponding Observables.

Try to do it in this way:

import { forkJoin } from 'rxjs'; const rowObjects$ = result.data.map(rd => this.myService.getObject(rd.id)); forkJoin(rowObjects$) .subscribe((object:any) => { //... }) 
Sign up to request clarification or add additional context in comments.

Comments

-1

You can use combineLatest to combine all the observables and wait until every observable fires at least once.

import {combineLatest} from 'rxjs'; ... let result = service.getResults(); const observablesToCombine = []; result.data.forEach((row:any) => { observablesToCombine.push(this.myService.getObject(row.id)); }) combineLatest(observablesToCombine).subscribe((object: Array<any>) => { //... }) 

4 Comments

combineLatest will emit each time any of the inner observables emits. The OP wants this to only happen whne all inner observables are complete.
@xandermonkey Not each time always but each time after every one of them is fired at least once. And I can't see where OP stated he wants to fire only once.
"after all the subscriptions of getObject(row.id) have finished". I downvoted because it's a wrong answer
@xandermonkey combineLatest will only fire after every inner observable fires at least once as well as forkJoin. The only difference between two of them is that the forkJoin performs parallel execution and finishes (completes) while combineLatest performs serial execution (using concat inside) and does not finish (complete). So, combineLatest should work well for OP as well. And also see: stackoverflow.com/a/41797505/1331040

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.