Shopify / ui-extensions

MIT License
265 stars 37 forks source link

Blocking behavior not working: useBuyerJourneyIntercept + useApplyCartLinesChange #2367

Open AntoineColorz opened 5 days ago

AntoineColorz commented 5 days ago

Packages involved in the issue

@shopify/cli : 3.67.1, @shopify/ui-extensions : 2024.7.x, @shopify/ui-extensions-react": 2024.7.x

Describe the bug

When using useBuyerJourneyIntercept to block the customer at the shipping step in conjunction with useApplyCartLinesChange for all line items, the blocking behavior doesn't work as expected.

Steps to reproduce the behavior:

  1. Clone the following repository: https://github.com/AntoineColorz/bug-intercept-buyer-journey/
  2. Run the project (npm run dev)
  3. Use choice_3 (steps as described in the screencast)

Expected behavior

The blocking behavior should prevent the customer from proceeding past the shipping step.

Screenshots

https://github.com/user-attachments/assets/351ff041-d855-460e-9ecb-37e5b46a6e22

dnagoda commented 5 days ago

Hi @AntoineColorz 👋

I'm not able to reproduce this issue using your test code. When selecting Choice 3 and then clicking the Continue to payment button, I get a warning from the buyer journey intercept, You must provide details for choice 3.

Are there any warnings in your dev tools console? Are there any other details you can provide?

AntoineColorz commented 4 days ago

hi @dnagoda. Thanks for testing that.

No I don't have any error in the console.

To reproduce the bug, you need to have more than one product in the basket for there to be more than one change on the cartLines. You also have to change your choice several times.

https://github.com/user-attachments/assets/baaa3f30-a577-425f-8e8f-811b9434346c

AntoineColorz commented 4 days ago

here's a dumb version that shows the bug. If I put a blocking without any condition I manage from time to time to pass anyway.

import React, { useState } from "react";
import {
  reactExtension,
  BlockStack,
  useBuyerJourneyIntercept,
  useApplyCartLinesChange,
  useApi,
  ChoiceList,
  Choice,
  Text,
} from "@shopify/ui-extensions-react/checkout";

export default reactExtension(
  "purchase.checkout.shipping-option-list.render-before",
  () => <Extension />
);

const choiceListExemple = [
  { label: "Choice 1", value: "choice_1" },
  { label: "Choice 2", value: "choice_2" },
  { label: "Choice 3", value: "choice_3"},
];

function Extension() {
  const { lines } = useApi();

  const [selectedChoice, setSelectedChoice] = useState("choice_1");

  const applyCartLinesChange = useApplyCartLinesChange();
  const cartLines = lines.current;

  useBuyerJourneyIntercept(() => {
    return {
      behavior: "block",
      reason: "block every time",
      errors: [
        {
          message: "normally you should never pass",
        },
      ],
      perform: () => {
        console.log("🚩 _ BLOCK _ 🚩", performance.now());
      },
    };
  });

  return (
    <BlockStack>
      <ChoiceList
        name="requestedTest"
        onChange={(value) => onChoiceListChange(value)}
        value={selectedChoice}
        variant="group"
      >
        {choiceListExemple.map((choice) => (
          <Choice
            id={`${choice.value}`}
            key={`${choice.value}_key`}
          >
            <Text>{choice.label}</Text>
          </Choice>
        ))}
      </ChoiceList>
    </BlockStack>
  );

  async function onChoiceListChange(value) {
    setSelectedChoice(value);

    const customAttribute = [
      {
        key: "choice",
        value: value,
      },
    ];

    for (const cartLine of cartLines) {
      await applyCartLinesChange({
        type: "updateCartLine",
        id: cartLine.id,
        attributes: customAttribute,
      });
    }
  }
}

https://github.com/user-attachments/assets/636062e5-d8dd-49de-ad75-967d6168f451

patryk-smc commented 19 hours ago

here's a dumb version that shows the bug. If I put a blocking without any condition I manage from time to time to pass anyway.

useBuyerJourneyIntercept was always unreliable like shown on your video and I don't think there is much you can do. Validation functions are better IMO, although their Input API is bit limited