Home > Mobile >  RxJs. Why a subject emits only once after mergeMap?
RxJs. Why a subject emits only once after mergeMap?

Time:01-25

I have a few links, which one represents a user's active order. When a user clicks on it, I want to send an HTTP DELETE request to an API. I have a function in my component ts file, which get called from my template like so:

// Component
interface CancelCommand {
    orderId: string
}
private cancelCommands = new Subject<CancelCommand>();

/* Get called from a template on click, like so 
          <a ... (nzOnConfirm)="cancel(ord.id)">Cancel</a> */
cancel(orderId: string) {
    this.cancelCommands.next({
        orderId: orderId
    })
}

I'm subscribing to the Subject cancelCommands in my ngOnInit:

// Component
ngOnInit(): void {
    this.cancelSub = this.cancelCommands.pipe(
        mergeMap((command) => this.service.cancelOrder(command)))
    ).subscribe()
}

In the service the cancelOrder function just calling HttpClient

// The Service
cancelOrder(command: CancelCommand) : Observable<CommandResponse> {
      return this.http.delete<CommandResponse>(`${this.url}/${command.orderId}`)
}

My question is, why does the observable with this.cancelSub subscription stops emitting values after first order's cancellation?

CodePudding user response:

@PilgrimViis Have you checked if the observable this.cancelSub really completes?

@TmTron I checked if mergeMap completes when the source observable completes which is not the case here: https://stackblitz.com/edit/rxjs-qthnmy?devtoolsheight=33&file=index.ts

CodePudding user response:

Thank you all guys for your tips! With your help, I've figured it out. The error happened when one of my requests return an error and the observable stops. I've fixed it like this, looks like it's ok.

    this.cancelSub = this.cancelCommands.pipe(
      mergeMap((command) => this.service.cancelOrder(command)),
      catchError((_, caught) => caught) // new line
    ).subscribe()

CodePudding user response:

if this.service.cancelOrder(command) completes it closes this.cancelSub for this use switchMap instead of mergeMap to create a new observable for each request.

// Component
ngOnInit(): void {
    this.cancelSub = this.cancelCommands.pipe(
        switchMap((command) => `this.service.cancelOrder(command)`))
    ).subscribe()
}
  •  Tags:  
  • Related