Checkout UI Extension Problem - ChoiceList onChange blocks radio button styes

Checkout UI Extension Problem - ChoiceList onChange blocks radio button styes

Brendan_Newell
Shopify Partner
4 0 0

I am having an issue with a checkout UI extension that adds an additional choice list when a certain shipping method is selected. When the customer selects an option in this choice list, it saves/updates a cart attribute that is then used in a post-checkout flow in an external application. Everything in the extension works correctly except the selected styling state does not work correctly when updating the cart attributes in the onChange event.

 

Sample Code (simple example to demonstrate problem)

 

 

import {extension, ChoiceList, Choice, Text} from '@shopify/ui-extensions/checkout';

export default extension(
  'purchase.checkout.shipping-option-item.details.render',
  async (root, {applyAttributeChange}) => {
    const choices = [];
    choices.push(root.createComponent(Choice, {id: 1}, root.createComponent(Text,undefined,'Item 1')));
    choices.push(root.createComponent(Choice, {id: 2}, root.createComponent(Text,undefined,'Item 2')));
    choices.push(root.createComponent(Choice, {id: 3}, root.createComponent(Text,undefined,'Item 3')));

    const choiceList = root.createComponent(
      ChoiceList,
      {
        name: 'cnc-outlet',
        value: 'first',
        variant: 'group',
        onChange: updateAttributes,
      },
      choices,
    );
    root.replaceChildren(choiceList);

    async function updateAttributes(outlet) {
      await applyAttributeChange({
        key: 'cnc-outlet',
        type: 'updateAttribute',
        value: outlet.toString(),
      }).then(result => {
        console.log(result);
      });
    }
  },
);

 

When the "Click and Collect" option is selected, a list of options are presented:

Brendan_Newell_0-1712119442223.png

When the customer selects one of these options, it becomes the selected choice in the list - however only the radio button border gets highlighted:

Brendan_Newell_1-1712119486113.png

However, if the onChange handler does not call applyAttributeChange then the styling works as expected:

 

import {extension, ChoiceList, Choice, Text} from '@shopify/ui-extensions/checkout';

export default extension(
  'purchase.checkout.shipping-option-item.details.render',
  async (root, {applyAttributeChange}) => {
    const choices = [];
    choices.push(root.createComponent(Choice, {id: 1}, root.createComponent(Text,undefined,'Item 1')));
    choices.push(root.createComponent(Choice, {id: 2}, root.createComponent(Text,undefined,'Item 2')));
    choices.push(root.createComponent(Choice, {id: 3}, root.createComponent(Text,undefined,'Item 3')));

    const choiceList = root.createComponent(
      ChoiceList,
      {
        name: 'cnc-outlet',
        value: 'first',
        variant: 'group',
        onChange: updateAttributes,
      },
      choices,
    );
    root.replaceChildren(choiceList);

    async function updateAttributes(outlet) {
      console.log('applyAttributeChange removed')
      /*await applyAttributeChange({
        key: 'cnc-outlet',
        type: 'updateAttribute',
        value: outlet.toString(),
      }).then(result => {
        console.log(result);
      });*/
    }
  },
);

 

Brendan_Newell_2-1712119694969.png

When observing in the browser, I can see that the radio does briefly show as selected but this disappears and just shows the border - it appears that waiting on the async call is interrupting the display/state of the button?

 

I've tried several different approaches but have been unable to both call applyAttributeChange in the onChange handler and have the styling be correct - its one or the other.

 

Any help much appreciated.



Replies 2 (2)

EnriqueMelero
Shopify Partner
5 1 1

When you use applyAttributeChange Shopify re-renders all the attached extensions, so the ChoiceList component tries to detect a Choice with the id 'first'. If there is no Choice with the id 'first', then the selection disappears when the component renders again.

 

You need to update the value of the ChoiceList with the selected Choice. Store the selected id on a variable and assign it to the value prop.

Brendan_Newell
Shopify Partner
4 0 0

Thanks for your help. Could you show a quick example of what you mean? I tried what I thought you were suggesting but still see the same behaviour. Just to clarify as well - the selection itself is definitely being persisted because the border of the radio button does get highlighted and the value is always stored and passed through to subsequent steps correctly.