1
votes

I am trying understand how fork join rxjs operator behavior and I made a little tests. I've found out that after fork Join emit a the first value its unsubscribe or complete (Not sure) and cannot be produce any values. Is it correct ? My code here "rxjs "forkjoin" example"

From the code attached. Only after clicking on both buttons forkJoin can emit the values from observable 1 and observable 2 as expected. But the second time i did this test. Clicking on buttons 1, 2, Nothing happens. This behavior is not documented and I am not sure if I did something wrong. Can someone give me clarification on it ? Thanks

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, combineLatest, forkJoin, from, fromEvent, 
interval, Observable, of, zip } from 'rxjs';
import { delay, map, take } from 'rxjs/operators';

 @Component({
  selector: 'my-app',
  template: ` 
    RXJS EXAMPLE. See Console

     <button (click)="test1()"> click 1</button> 
    <button (click)="test2()"> click 2</button> 
     <div *ngIf="data">
    {{data}}
 
    </div>
   `,  
})

export class AppComponent  {

   private source1 = new BehaviorSubject<number>(1);
   obs1$ = this.source1.asObservable();
  private source2 = new BehaviorSubject<number>(1);
   obs2$ = this.source2.asObservable();

test1(){

 var randomVal = Math.floor(Math.random() * 10)*2;
 this.source1.next(randomVal);
 this.source1.complete();

}

test2(){  
 var randomVal = Math.floor(Math.random() * 10);
 this.source2.next(randomVal);
 this.source2.complete(); 
 }

 constructor() {
   forkJoin([ this.obs1$,  this.obs2$])
  .subscribe(res => {
   this.data = res; });
}}
  
1

1 Answers

2
votes

From forkJoin documentation you can see:

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 lifecycle of passed observables, but also throughout it, try out combineLatest or zip instead.

This is what happens in your example: after 1 click stream is competed and next values ignored.

In order to change this behavior, you could remove .complete() call and use:

  • combineLatest to emit value on any new click
  • zip to emit when both buttons were clicked