Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJS forkJoin does not complete

When I subscribe to getAllSubModules forkJoin executes all those observables without error but does not complete. I know forkJoin completes only after all its observables completed but as a proof I see '-----' 3 times in console which confirm everything is successful so all its observables completed.

 getSubmodules(id): Observable<any> {
    return this.authService.getToken()
      .flatMap((token) => this.http.get(`${this.URL}/ROS/applications/modules/${id}/subModules?token=${token}`))
      .map((res: any) => res.data.map((subModule) => this.mapSubModules(subModule)));
  }
  getAllSubmodules(): Observable<any> {
    const tasks = [];
    this.modules.forEach((module: AppModule) => {
      const obs = this.getSubmodules(module.id).map((subModules) => {
        this.allSubModules[module.id] = subModules;
        console.log('--------------------');
      });
      tasks.push(obs);
    });
    return Observable.forkJoin(...tasks).retry(2);
  }
  mapSubModules(moduleData) {
    if (moduleData.id) {
      const subModule = <SubModule> {
        id: moduleData.id,
        parentId: moduleData.parentId,
        typeId: moduleData.typeId,
        name: moduleData.name.az,
        active: true
      };
      return subModule;
    }
  }

This code is not executed when using forkJoin:

 this.universityService.getAllSubmodules().subscribe(() => {             
        // --- Below is not executed!--
        console.log('subModules in Report Co');
        console.log(this.universityService.allSubModules);
        this.checkUrl();
        this.showChild = true;
      }, (er) => console.log(er));

but when I use combineLatest instead of forkJoin it works as expected. So what is problem?Hope someone give advice.

like image 789
Vugar Abdullayev Avatar asked Nov 23 '17 08:11

Vugar Abdullayev


People also ask

Does forkJoin complete?

If no input observables are provided (e.g. an empty array is passed), then the resulting stream will complete immediately. forkJoin will wait for all passed observables to emit and complete and then it will emit an array or an object with last values from corresponding observables.

What happens if observable fails in forkJoin?

Be aware that if any of the inner observables supplied to forkJoin error you will lose the value of any other observables that would or have already completed if you do not catch the error correctly on the inner observable.

Does forkJoin maintain order?

It's worth noting that the forkJoin operator will preserve the order of inner observables regardless of when they complete.

Is forkJoin asynchronous?

In fork/join patterns, work is forked (split) into a set of tasks that can be executed asynchronously.

How does forkjoin work in Java?

In order for the resulting array to have the same length as the number of input observables, whenever any of the given observables completes without emitting any value, forkJoin will complete at that moment as well and it will not emit anything either, even if it already has some last values from other observables.

What happens if forkjoin fails?

If any given observable errors at some point, forkJoin will error as well and immediately unsubscribe from the other observables. Optionally forkJoin accepts a resultSelector function, that will be called with values which normally would land in the emitted array.

What happens if observables are not provided in forkjoin?

If no input observables are provided (e.g. an empty array is passed), then the resulting stream will complete immediately. forkJoin will wait for all passed observables to emit and complete and then it will emit an array or an object with last values from corresponding observables.

Can forkjoin emit more than once?

That means forkJoin will not emit more than once and it will complete after that. If you need to emit combined values not only at the end of the lifecycle of passed observables, but also throughout it, try out combineLatest or zip instead.


1 Answers

Your expectation is incorrect. Having console.log('--------------------') emitted 3 times only means that you have received 3 onNext events. forkJoin waits for all observables to complete.

Try what happens if you look at the individual streams with .do(next=>{},err=>{},complete => console.log('completed')) or explicitly define when your streams should complete using .take(1) and/or .timeout(1000).

Does authService..getToken() complete after emitting one value?

like image 117
Mark van Straten Avatar answered Dec 20 '22 09:12

Mark van Straten