How to unsubscribe from an Observable returned by forkJoin?
Asked Answered
U

2

18

In my Angular2-typescript app, I'm using forkJoin to return an Observable only once all the parallel HTTP calls were made.

Issue: the subscription callback keeps being executed indefinitely

Here is my code:

http.service

import {Http} from "@angular/http";

constructor (private _http: HTTP) {}

makeGetRequest(....) {
    return this._http.get(URL)
           .map (res => res.json)
           .toPromise();

my.service

import {Observable} from "rxjs/Observable";
import {HttpService} from "http.service"

constructor (private _httpService: HttpService) {}

myMethod(): Observable<any[]> {
 return Observable.forkJoin(
            this._httpService.makeGetRequest(
                URL1
            ),
            this._httpService.makeGetRequest(
                URL2
            )
        )
}

my.component

import MyService from "my.service";
import Subscription from "rxjs";

constructor (private _service: MyService) {}

mySub: Subscription;

ngOnInit() {
    this.mySub = this._service.myMethod.subscribe(data => {
         data.forEach(console.log(data));
         this.mySub.unsubscribe();
     }
}

What I tried (same issue):

  • return an Observable in Http.service rather than a Promise
  • in my.component use .first().subscribe() instead of just subscribe()
  • put this.mySub.unsubscribe(); at the end of ngOnInit rather than inside the subscribe callback (also with setTimeout(() => ....))
Unselfish answered 4/11, 2016 at 18:34 Comment(4)
What do you mean with 'the subscription callback keeps being executed indefinitely'?Garvey
The question doesn't make sense. forkJoin joins the results from completed observables and shouldn't be unsubscribed because it has a single value. If you have troubles with being executed indefinitely, please, provide an MCVE that can replicate your issueNichellenichol
@estus you're right. apparently this was happening because there subscription was instantiated twice and that caused the issue. Feel free to answer the question, I'll accept it ;)Unselfish
Sure. It's good that it was resolved easily.Nichellenichol
N
56

As forkJoin reference says, it

Runs all observable sequences in parallel and collect their last elements.

This means that the operator gets values from completed observables and returns a completed observable with single value. There's no need to unsubscribe from it.

Nichellenichol answered 4/11, 2016 at 20:1 Comment(4)
What if we want two forkjoins? I'm having trouble because I call .forkjoin() multiple times in my app - I think rxjs doesnt like that :(Lazare
What do you mean exactly? You can use multiple forkJoins. They just return observables that can be combined in any way. There shouldn't be any problems with that as long as your expectations from them are correct. If you have a specific case in mind, consider asking a new question that explains it and contains stackoverflow.com/help/mcve .Nichellenichol
In one component, I do a forkJoin to get certain results. I push some of those results into an array and then do a forkJoin with that array. But second forkJoin never returns data even though no error is ocurring. If I take out the initial forkJoin, then it works fine. Our forkjoin is actually an observable itself, and I think when I call it a second time, its still already set to the original values?Lazare
After further testing, seems to be a timing issue. My second forkjoin runs as long as I put a setTimeout around it and stall it out at 3 seconds (haven't tried more/less time yet). This surprises me since due to my code I'd assume my first forkjoin completes before the second one fires..Lazare
F
2

You can cancel it. Let's say observables is an array of http requests you prepared to trigger (executed via httpClient).

this.forkJoinSubscription = forkJoin(observables).subscribe(responses => {
    . . . do something
});

this.forkJoinSubscription.unsubscribe();

You may notice in your network tab that those requests were cancelled.

Family answered 11/10, 2019 at 14:53 Comment(3)
Do you know that this happens for a fact, or just hope it does that?Pecan
Ok, so this answer is from 3.5 years ago :D, but if you notice in my answer "You may notice in your network tab that those requests were cancelled." so yeah, it happens (at least then it happened)Family
OK, it was ambiguous meaning, thanks English :) "May" meaning it might happen. But you're saying it actually does happen - you saw it in the network tab.Pecan

© 2022 - 2024 — McMap. All rights reserved.