Search code examples
angularrxjsfork-join

Wait for Http calls Angular 4 ForkJoin


Observable.forkJoin(this.cdsDataService.getServersForComponent().map(one => this.Servers = one),
    this.cdsDataService.getComponentForServer().map(two => this.Components = two))
    .subscribe(res => {

        //for these ids more http calls are made 
        for (let comp of this.Components) {
            this.compIds.push(comp.ID);
            //does not wait for this http call to complete
            this.getObjectsById();
            SomeMethod();
        }}
    );

getObjectsById()
{
    let observableBatch = [];
    this.compIds.forEach((key) => {
        observableBatch.push(this.cdsDataService.getComponentLinks(key).subscribe(p => {
            //console.log(key);
            for (let it of p) {
                let nodelink = {from: key, to: it.ID, color: "blue"};
                this.componentLinkData.push(nodelink);
            }
            // console.log(p);
        }));
    });
    return Observable.forkJoin(observableBatch);
}

getComponentForServer() returns ids that are used by getObjectsById()

getObjectsById() loops through ids and makes http calls for each id.

I am not able to make the program wait for all the calls from getObjectsById() to finish. It simply jumps to SomeMethod();

Help would be greatly appreciated.


Solution

  • You are essentially doing a subscribe() inside a subscribe(). Because http calls are asynchronous, the code just executed without waiting for the result.

    Use switchMap or concatMap instead:

    Observable.forkJoin(this.cdsDataService.getServersForComponent(), this.cdsDataService.getComponentForServer())
        .switchMap(([servers, components]) => {
            let observableBatch = components.map(comp => this.cdsDataService.getComponentLinks(comp.ID)
                .map(p => {
                    this.componentLinkData = p.map(it => ({from: comp.ID, to: it.ID, color: "blue"}))
                }));
            return Observable.forkJoin(observableBatch)
        })
        .subscribe(()=>{
            SomeMethod();
        })