Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better support for optimistic UI updates with cart actions #195

Open
robbieaverill opened this issue Oct 7, 2021 · 0 comments
Open

Better support for optimistic UI updates with cart actions #195

robbieaverill opened this issue Oct 7, 2021 · 0 comments

Comments

@robbieaverill
Copy link
Contributor

Scenario 1: add to cart

As a customer, on the product list page I click the "add to cart" button for a product I want to purchase 5 times in quick succession. This would call commerce.cart.add(cartId, productId, 1) 5x.

Developers cannot easily optimistically add an item like this to their cart. Having TypeScript would help because the cart object would be easily predictable. The API is currently not idempotent, so the 5x calls would result in the line item having a quantity of 5. We could change the API so it would result in a quantity of 1 after the 5th call.

Ideally Commerce.js provides an abstracted API somehow for developers to easily update their UIs with optimistic cart additions, and a way to revert that addition if something fails.

The quantity is one aspect of this, but also we'd like to be able to update the cart totals etc as well. We currently suggest that devs could grey out their totals while these operations are in-flight, but Commerce.js might also be able to get the product price from state somewhere and use that to be optimistic about cart total changes before the API response has been returned.

Scenario 2: update item in cart

As a customer, on the cart page, I click the "increase quantity" button on my cart line item three times, then click the "decrease quantity" button once, then click "increase quantity" twice more.

Again, developers cannot easily optimistically update their cart right now. As above, quantity can be tracked and updated, and totals can be greyed out until API responses have been returned, but the logic for this ideally could be contained in Commerce.js rather than expecting the developer to write it.

An example of how they might implement it now (with React):

const updateItemInCart = (cartId, lineItemId, quantity) => {
  // Optimistically update the line item quantity
  this.setState({ cart: { [lineItemId]: quantity } };
  // Call Commerce.js
  commerce.cart.update(cartId, lineItemId, quantity)
    // Revert quantity changes if the API call fails
    .catch(() => {
      this.setState((originalState) => {
        cart: { [lineItemId]: originalState.cart[lineItemId].quantity - quantity },
      });
    });
};

We are hoping that Commerce.js will be more state-aware, so this would be a good feature to add if possible. We can debounce API requests to help with the examples above, but if users wait to click the buttons for slightly longer than the debounce time then the issue resurfaces. There might be a solution involving some kind of promise queue that cancels previous requests and honours the response from the last API call in the queue (assuming the API calls are idempotent).

API wise:

  • Add to cart is not idempotent
  • Update item in cart is idempotent
  • All cart APIs should be updated to be idempotent
  • All cart APIs should be updated to return a cart object (they all return bespoke responses right now)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant