nick
nick

Reputation: 507

How to string together ConcatMaps and keep track of data

I have the following code

   from(this.dataSource2.data.filter(a => a.ProcessAction == ProcessAction.Capture)).pipe(
      concatMap(x => {
//this calls my first endpoint which requires data which must wait until the last call is done before calling
        return this.stripeService.capturePaymentIntent(x.PaymentIntentId, Math.floor(x.AmountToCharge * 100));
      }),
//this calls the second endpoint which must execute after the first and requires data from the first
      concatMap(y => {
        return this.orderService.createCashFlow(cashFlowRequest)
      }),
    ).subscribe({
      next: (response) => {
        //The response data will have an order number so I can query the original data to alter it as I need
        this.dataSource2.data.filter(a => a.OrderData.OrderNumber == response.OrderNumber).forEach(original => {
          original.StripeData!.PreAuthAmount = 0;
          original.StripeData!.Status = 'succeeded';
          original.Message = '';}
          );
      },
      error: (err) => {
        //each of the endpoints throw different errors and I don't have access to the order number in one of them so can't query the ordignal query
        this.dataSource2.data.error = err;

      }

So my question becomes how to I pass the original data from the original observable I created throughout the calls. Is there a better way to string my concatmaps together or to call sequential synchronous endpoints in Angular?

I have a list of urls I need to call, so I create observables from those with from() I then want each of these URLs to be called asyncronously so I use pipe and on the observable call concatMap to call the first endpoint. I then call concatMap again on the response from the first one and return that. I then subscribe to my observable which only has the result from the last endpoint.

I'm new to all this so any help is appreciated!

Edit: Just to make it clear it is this.dataSource2.data which I created the original observable from that I want to alter in the error response.

Upvotes: 1

Views: 85

Answers (1)

wlf
wlf

Reputation: 3393

Instead of relying on concatMap to nest your calls, use pipe to ensure sequential calling of service methods and availability of all previous observable values:

of(data)
  .pipe(
    switchMap((paymentId) =>
      capturePaymentIntent(paymentId).pipe(
        switchMap((intent) =>
          createCashFlow(intent).pipe(
            tap((cashFlow) => {
              console.log('Payment ID: ', paymentId);
              console.log('Payment Intent: ', intent);
              console.log('Cashflow: ', cashFlow);
            })
          )
        )
      )
    )
  )

Stackblitz: https://stackblitz.com/edit/rxjs-wlu4m1?devtoolsheight=60

Upvotes: 1

Related Questions