14
votes

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(() => ....))
2
What do you mean with 'the subscription callback keeps being executed indefinitely'?Picci
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 issueEstus Flask
@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 ;)dragonmnl
Sure. It's good that it was resolved easily.Estus Flask

2 Answers

43
votes

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.

0
votes

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.