Domiku
Domiku

Reputation: 21

Subscribe in subscribe in Angular rxjs

I have:

getSth(): void {
    this.service.functionName.pipe(
      takeUntil(this.destroy$),
      distinctUntilChanged(),
      map(res => res.event)
    ).subscribe(((response) => {
      this.getAnother(response);
    }));   }

getAnother(response): void {
    this.anotherService.anotherFunctionName(response).subscribe((res) => {
      this.result = res;
    });   }

I know that isn't a good solution to write subscribe in subscribe. How to fix it?

Upvotes: 1

Views: 2631

Answers (2)

Totati
Totati

Reputation: 1582

You have more options, there are some *map operators, that handle the flow differently. By your example you could use switchMap, which cancels your running observable (in your example the getAnother). There's a Operator Decision Tree in the docs, try it, it can help a lot.

You get switchMap with this logic:

  1. I have one existing Observable, and
  2. I want to start a new Observable for each value
  3. and cancel the previous nested Observable when a new value arrives
  4. where the nested Observable is calculated for each value

One other note, you should have your takeUntil to be placed last.

You could write something like this:

getSth(): void {
  this.service.functionName.pipe(
    // If service.functionName returns a new object every time distinctUntilChanged will do nothing as references won't be the same.
    // distinctUntilChanged(),
    switchMap(resp => this.anotherService.anotherFunctionName(resp.event))
    takeUntil(this.destroy$),
    ).subscribe((result) => {
      this.result = result;
    }));
}

Upvotes: 0

Emilien
Emilien

Reputation: 2761

Let's use switchMap :

getSth(): void {
  this.service.functionName.pipe(
    takeUntil(this.destroy$),
    distinctUntilChanged(),
    map(res => res.event),
    switchMap(response =>
      this.anotherService.anotherFunctionName(response)
    )
  ).subscribe(response => this.result = response);
}

Upvotes: 3

Related Questions