Search code examples
javascriptangulartypescriptrxjsobservable

Methode return status cancled when using take(1) and when not using it it is lunched multiplit time


handleRedirect is a method that calls two observable. the first is ValidateCartService.getValidateCart() with Observable type and the second ValidateCartService.setCart() . once the two methods are triggered and return status 201 it must make a redirect action with this.routingService.go({ cxRoute : 'checkout' }) ;

I've tried using this method. With this form, it is launched several times and the object is launched several times.

this.ValidateCartService.getValidateCart().subscribe((Element:any)=>{
        () => {
          this.ValidateCartService.setCart().subscribe((elementCheckout:any)=>{
              this.routingService.go({ cxRoute: 'checkout' });
          })
          ,
        (error) => {
          // Handle errors here
          console.error('Error occurred:', error);
        }
       
        }
      }
      )  
i tried to use this methode it. with this form i get status cancled
handleRedirect() {
    this.ValidateCartService.getValidateCart().pipe(
      take(1)
    ).subscribe(
      (element: any) => {
          this.ValidateCartService.setCart().pipe(
            take(1) 
          ).subscribe(
            (elementCheckout: any) => {
                this.routingService.go({ cxRoute: 'checkout' });
            },
            (errorCheckout: any) => {
              console.error('Error in setDefault information:', errorCheckout);
            }
          );
      },
      (error: any) => {
        console.error('Error occurred:', error);
      }
    );
    
  }
protected validateCartQuery$(
    userId : any,cartId:any
  ): Query<any> {
    return this.queryService.create<any>(
      () =>
        this.ValidateCart.validateCart(
          userId,cartId
        ),
      {
        reloadOn: this.getNavigationEvent(),
        resetOn: this.getNavigationEvent(),
      }
    );
  }

  validateCartState(
    userId : any,cartId:any
  ): any {
    return this.validateCartQuery$(userId,cartId).getState();
  }

  getValidateCart(
  ): any {
    let code : any
    let userId :any
    this.activeCartFacade.getActive().subscribe((cartItem:any)=>{
      code = cartItem.user?.uid === "anonymous"? cartItem.guid : cartItem.code
      userId = cartItem.user?.uid
    })
    return this.validateCartState(userId,code).pipe(
      map((state:any) => state ?? [])
    );
  }

this.ValidateCart.validateCart make a call to a config to start a call post with axios and the same for setCart.


Solution

  • You need to chain the observables which might be the problem, could you please modify the below function?

    use switchMap if you need the output of one observable to be used to fetch another observable

    getValidateCart(): any {
        return this.activeCartFacade.getActive().pipe(
          switchMap((cartItem: any) => {
            const code = cartItem.user?.uid === "anonymous" ? cartItem.guid : cartItem.code;
            const userId = cartItem.user?.uid;
            return this.validateCartState(userId, code).pipe(
              map((state: any) => state ?? [])
            );
          })
        );
      }
    

    You can also modify the below function to use switchMap(s)

    Also please add subscriptions and unsubscribe on destroy to avoid memory leaks!

    handleRedirect() {
        this.ValidateCartService.getValidateCart().pipe(
          take(1) // maybe you can remove this?
        ).pipe(
          switchMap((element: any) => {
            return this.ValidateCartService.setCart().pipe(
              take(1)
            ).pipe(
              tap((elementCheckout: any) => {
                this.routingService.go({ cxRoute: 'checkout' });
              })
            ))
        ).subscribe({
          error: (errorCheckout: any) => {
            console.error('Error in setDefault information:', errorCheckout);
          }
        })
      }