Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

108
Visualizações
avoid nested subscribe if there is a forkjoin inside

Here is my code in angular

this.service.save(body).subscribe(
    resp => {
       this.dialog.confirmation({
          message: 'save object successfully!'
       })
       .subscribe((ok) => {
            if(ok) {
               this.pro.status = resp.status;
            this.loadingData(resp);
            const s1 = this.service.getSummary(this.id);
            const s2 = this.service.getCost(this.id);
            forkJoin([s1, s2]).subscribe([r1, r2]) => {
               this.view = r1;
               this.list = r2;
            }
          }
        });
     }
);

So there are many levels of subscribe. Not only it is ugly also the result is wrong and I can't not find it out by debugging. How can I rewrite it with rxjs operators?

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

This should be roughly equivalent:

this.service.save(body).pipe(

  mergeMap(resp => 
    this.dialog.confirmation({
      message: 'save object successfully!'
    }).pipe(
      // This filter acts like your `if(ok)` statement. There's no 
      // else block, so if it's not okay, then nothing happens. The 
      // view isn't updated etc.
      filter(ok => !!ok),
      mapTo(resp)
    )
  ),

  tap(resp => {
    this.pro.status = resp.status;
    // If the following line mutates service/global state,
    // it probably won't work as expected
    this.loadingData(resp); 
  }),

  mergeMap(_ => forkJoin([
    this.service.getSummary(this.id),
    this.service.getCost(this.id)
  ]))

).subscribe([view, list]) => {
  this.view = view;
  this.list = list;
});
about 4 years ago · Juan Pablo Isaza Relatório

0

You can simplify it using the RxJS operators, like the following:

// import { EMPTY, forkJoin } from 'rxjs';
// import { map, mergeMap } from 'rxjs/operators';

this.service
  .save(body)
  .pipe(
    mergeMap((result) =>
      // Merge the main observable with the dialog confirmation one..
      // and map it to an object that contains the result from both observables.
      this.dialog
        .confirmation({ message: 'save object successfully!' })
        .pipe(map((confirmed) => ({ result, confirmed })))
    ),
    mergeMap(({ result, confirmed }) => {
      if (confirmed) {
        this.pro.status = result.status;
        this.loadingData(result);
        const s1 = this.service.getSummary(this.id);
        const s2 = this.service.getCost(this.id);
        return forkJoin([s1, s2]);
      }
      // Don't emit any value, if the dialog is not confirmed:
      return EMPTY;
    })
  )
  .subscribe(([r1, r2]) => {
    this.view = r1;
    this.list = r2;
  });

Note: To handle the memory leaks, it's highly recommended to unsubscribe from the observable when you don't need it anymore, and this can be achieved based on your use cases, such as assigning the subscribe function result to a Subscription variable and calling unsubscribe in ngOnDestroy lifecycle hook, or using a Subject with takeUntil operator and calling next/complete functions in ngOnDestroy.

And here is how to use the unsubscribe method for example:

// import { Subscription } from 'rxjs';

@Component({...})
export class AppComponent implements OnInit, OnDestroy {
    subscription: Subscription 
    ngOnInit(): void {
      this.subscription = this.service.save(body)
        // >>> pipe and other RxJS operators <<<
        .subscribe(([r1, r2]) => {
          this.view = r1;
          this.list = r2;
        });
    }
    ngOnDestroy() {
        this.subscription.unsubscribe()
    }
}

You can read more about that here: https://blog.bitsrc.io/6-ways-to-unsubscribe-from-observables-in-angular-ab912819a78f

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda