简体   繁体   中英

Angular4 Chain of observables

I have a problem with chain of observables, one map doesn't wait for response and it destroys my idea. I have something like this. I have components and functions inside.

Step3Component

  addCardAndGotoStep3() {
      this.checkout.newCard = this.appNewCard.newCard;
      this.checkout.addCardAndGotoStep3(this.appNewCard).subscribe();
  }

CheckoutComponent

  addCardAndGotoStep3 (newCardForm) {

    if( !newCardForm.isValid) { return; }
    // billingUtilService.checkout.newCard = vm.newCard;
    return this.initPaymentMethods()
        .map( () => {
            // billingUtilService.addCardUi(vm)
            return this.billingUtilService.addCardByRest(this);
        })
        .switchMap( (newCardId) => {
            const model = {};
            console.warn('newCardId' + newCardId);
            console.error(newCardId);

            const card: any  = {};
            card.uuid = newCardId;
            card.fourDigits = this.newCard.cardNumber.slice(-4);
            card.name = this.newCard.name;
            card.id = card.fourDigits;
            this.billingUtilService.checkout.screenPaymentMethod = card;
            this.routeService.gotoState('app.loggedIn.team.checkout.step-3');
            return newCardId;
        })
        .catch( (response) => {
            this.alertService.addValidationAlert(this.tr.TR_CARD_NOT_ACCEPTED);
            return Observable.throw({response});
        });

};

BillingUtilService

addCardByRest(vm) {
    const req = this.createPaymentMethodRequest(vm.newCard);
    return this.billingRest.addAccountPaymentMethod(req)
        .map( (paymentMethodId) => {
            console.warn('successs' + paymentMethodId);
            return paymentMethodId;
        })
        .catch( (response) => {
            console.log('it doesnt work');
            return Observable.throw(response);
        });

BillingRestService

addAccountPaymentMethod (accountPaymentMethodRequest) {
        return this.http.post(this.restUrl + this.restPrefix + '/addAccountPaymentMethodCC', accountPaymentMethodRequest, {observe: 'response'})
            .map( (response: any) => {
                if (! this.utilService.isDefined(response.body)) {
                    return Observable.throw({});
                }
                return response.body.paymentMethodId;
            })
            .catch((response) => {
                this.logger.debug("addAccountPaymentMethodCatch")
                this.logger.exception('addAccountPaymentMethod : Ajax Error')(response);
                return Observable.throw(response);
            });
    };

I have a problem with this part of code

 .map( () => {
            // billingUtilService.addCardUi(vm)
            return this.billingUtilService.addCardByRest(this);
        })
        .switchMap( (newCardId) => {
            const model = {};
            console.warn('newCardId' + newCardId);
            console.error(newCardId);

that switchMap doesn't wait for return from addCardByRest. Did i confuse something ? Other service returns an observable, so i had to use some flattening Operator, but actually it doesn't work.

Console output:

newCardId[object Object]                   checkout-controler.service.ts
Observable {_isScalar: false, source: Observable, operator: CatchOperator} checkout-controler.service.ts
succes: [here is the RightUUid]            checkout-controler.service.ts

Use concatMap and subscribe to the last observable instead of using switchmap.

 .concatMap( () => {
        // billingUtilService.addCardUi(vm)
        return this.billingUtilService.addCardByRest(this);
    })
    .subscribe( (newCardId) => {
        const model = {};
        console.warn('newCardId' + newCardId);
        console.error(newCardId);
    }, error => {
     // Do something with error here instead of catch
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM