spartacus icon indicating copy to clipboard operation
spartacus copied to clipboard

ActiveCartService.requireLoadedCart() does not emmit any value

Open vitalii-fedoryshyn opened this issue 2 years ago • 4 comments

Describe the bug I recognize that behaviour of ActiveCartService.requireLoadedCart() changes after upgrade to 6.1(we upgrade from 4.3.3). So under some circumstances this method does not emmit any value.

Tell us the version of Spartacus

  • Library version: 6.3

To Reproduce This issue can be quite related to timing as well, so I just describe example using which you can reproduce it 100% sure. Steps to reproduce the behavior:

  1. Add custom logic which on 'CartAddEntrySuccessEvent' add produc 'A' to cart
  2. Go to PDP of product 'B' and press add to cart.
  3. Got to cart page. You expect to see product 'B' and product 'A' in your cart.
  4. In reality to see only product 'B'

Expected behavior requireLoadedCart() emit value when cart is loaded.

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: macOS(any)
  • Browser: chrome, firefox(any)
  • Version: lattest

Additional context So issue is that 'this.activeCartId$' emmit value but 'cartSelector$' has no value yet, because cart is loading(in example which I describe it's loading after add to cart click). As a result withLatestFrom(cartSelector$) no value emmit, see https://rxjs.dev/api/index/function/withLatestFrom

Fix/Solution Change order to same what you have at version 4.3.3, so start pipe from 'cartSelector$' which will emmit value after cart load

Screenshot 2023-08-22 at 10 54 13

vitalii-fedoryshyn avatar Aug 22 '23 09:08 vitalii-fedoryshyn

Hi @vitalii-fedoryshyn Thank you for creating the ticket and for your detailed analysis!

  1. What is the real use case you need it for, to be fixed?
  2. Would you mind reproducing this issue in an OOTB Spartacus, commiting your minimal reproduction customizations and sending us a link to your github repo, please?

Platonn avatar Sep 12 '23 13:09 Platonn

After upgrade of spartacus to 6.1 from 4.3, some production functionality was not working correctly. Issues was very hard to reproduce, but for our luck was able to identify root. It can be common issue for any spartacus 6.x clients, that's why I decide to report it.

  1. What is the real use case you need it for, to be fixed:
  • some times click on add to cart didn't bring any results(after page reload works ok)
  • Custom functionality similar to Quick Order or something like add bundle to cart(adding few different product) not work
  1. Sorry I wouldn't do that. Normally I bring a lot of details, as well as scenario how to reproduce wrong spartacus behaviour. And a fix as well, by the way...

vitalii-fedoryshyn avatar Sep 12 '23 13:09 vitalii-fedoryshyn

@Platonn you as well can change OCC endpoint and delay for GET /cart call for example for 30 second. You expectation: after PDP load click on add to cart will add product after cart loaded. Reality: Nothing happens.

Real case for slow networks or some slow get cart

vitalii-fedoryshyn avatar Sep 12 '23 13:09 vitalii-fedoryshyn

@Platonn We got the same issue on a B2B Project in the production environment, causing products to be added to the cart unexpectedly or after the order is placed.

Library version: 5.1

Replication with Slow Internet and Low-End Devices:

This issue becomes particularly pronounced and easily reproducible under specific conditions:

  • Network Constraints:

    • Devices operating on slow or limited internet connections.
    • Instances where network latency or bandwidth limitations are prevalent.
  • Device Characteristics:

    • Usage on low-end devices susceptible to processing delays.

Issue Overview:

The current functionality exhibits an unexpected behavior during cart processes, leading to potential inconsistencies in the cart operations flow.

Flow Description:

  1. User Triggers Add to Cart:

    • Cart processes increment by 1.
    • Successful completion of the add-to-cart action decrements the cart processes by 1.
  2. Cart Reload Event:

    • Upon completion, a cart reload event is triggered.
    • cart loading state is set to true.
  3. Subsequent Add to Cart Action:

    • User attempts to add another product to the cart.
    • Invokes the requireLoadedCart.
    • requireLoadedCart fetches the activeCartId$.
    • cart loading state is still true.
    • Decision not to emit occurs due to the filter condition:
      .pipe(filter((cartState) => !cartState.loading || !!this.checkInitLoad))
      
  4. Cart Loading State Transition:

    • Over time, the loading state transitions to false, signifying successful cart loading.
    • Passes through the filter condition due to !cartState.loading.
    • Emits successfully.
  5. Issue Arises - withLatestFrom Behavior:

    • However, withLatestFrom(cartSelector$) does not emit.
    • Stays in a holding state due to the inherent nature of withLatestFrom, waiting for emission from this.activeCartId$.
  6. After place order:

    • After the user places an order in the same browser.
    • The new active cart will be loaded and emitted.
    • The previous stuck process will be unstuck adding products to the new cart.

Impact and Consequences:

This behavior results in the withLatestFrom operator not emitting as expected, causing a halt in the cart operation flow even after the successful loading of the cart. Consequently, this disrupts subsequent actions relying on updated cart information, affecting user cart interactions and order finalization.

Additional Context:

A workaround has been implemented to mitigate this issue.

...
const cartSelector$ = (
      forGuestMerge
        ? this.cartEntity$.pipe(filter(() => !Boolean(getLastValueSync(this.isGuestCart()))))
        : this.cartEntity$
).pipe(filter((cartState) => !cartState.loading || !!this.checkInitLoad));
 return combineLatest([this.activeCartId$, cartSelector$]).pipe(
 ...
 );

sebospc avatar Nov 27 '23 05:11 sebospc