We're moving the community! Starting July 7, the current community will be read-only for approx. 2 weeks. You can browse content, but posting will be temporarily unavailable. Learn more

Hydrogen: How do you recieve the action data when you submit a CartForm?

Hydrogen: How do you recieve the action data when you submit a CartForm?

ajLonsway
New Member
4 0 0

So we are trying to do some validation for our cart using the barebones Hydrogen quickstart in TypeScript, but we are having issues using the CartForm component. 

 

Whenever you submit a cart form to update some attributes, Hydrogen uses the <CartForm> component like a form.

 

 

// in app/components/Cart.tsx
function CartLineUpdateButton({ children, lines, }: { children: React.ReactNode; lines: CartLineUpdateInput[]; }) { return ( <CartForm route="/cart" action={CartForm.ACTIONS.LinesUpdate} inputs={{lines}} > {children} </CartForm> ); }

 

 

 

By default, we are given an action in `app/routes/($locale).cart.tsx` that receives the submitted information.

 

 

 

 

// in app/routes/($locale).cart.tsx
export async function action({request, context}: ActionFunctionArgs) { ... return json( { cart: cartResult, errors, analytics: { cartId, }, }, {status, headers}, );

 

Typically in React, the action returns information to whatever route submitted the form with "useActionData". You can see an example in the official React documentation: https://reactrouter.com/en/main/hooks/use-action-data#useactiondata

 

 

 

 

export default function SignUp() {
  const errors = useActionData();

  return (
<Form method="post"> ... <p> <button type="submit">Sign up</button> </p> </Form> ); }

 

However, when attempting to receive information from the built-in action in `app/routes/($locale).cart.tsx`, the value always comes back as "undefined". This is even after returning to the page, forcing a reload.

 

 

// in app/routes/($locale).cart.tsx

export default function Cart() { const actionData = useActionData(); console.log("action data: " + actionData); // always undefined

 

How can we receive this information? Where does it go? We would like to use the "errors" value for some form validation, and display any errors. But without the action's return value, we can never display anything in addition. We could use some help figuring this out.

 

 

 

 

Replies 6 (6)

Weaverse
Shopify Partner
82 27 38

You can try adding a "fetcherKey" to the Form and then use the "useFetcher" hook with that key to get the result of the form action.

https://remix.run/docs/en/main/components/form#fetcherkey
https://remix.run/docs/en/main/hooks/use-fetcher#key

 

Helping merchants build super unique, high-performance storefronts using Weaverse + Hydrogen.
Looking for Development & Agency partners.
If you find the answer helpful, give it a thumbs up!
Our App: Theme Customizer for Shopify Hydrogen
Join our Weaverse + Hydrogen community: Weaverse Community
ajLonsway
New Member
4 0 0

Adding a fetcherKey only gives me the result {"Form":{},"state":"idle"} , which is not the format as the action.

 

function CartLineUpdateButton({
  children,
  lines,
}: {
  children: React.ReactNode;
  lines: CartLineUpdateInput[];
}) {
  const fetcher = useFetcher({key: "cart-increment"});
  
  console.log(JSON.stringify(fetcher));

  return (
    <CartForm
      fetcherKey='cart-increment'
      route="/cart"
      action={CartForm.ACTIONS.LinesUpdate}
      inputs={{lines}}
    >
      {children}
    </CartForm>
  );
}

What is this information, and how can we get the component to update when the form is submitted without refreshing the page? Is an effect required?

Weaverse
Shopify Partner
82 27 38

 You can try to retrieve the "fetcher.data" result with "useEffect"

function CartLineUpdateButton({
  children,
  lines,
}: {
  children: React.ReactNode;
  lines: CartLineUpdateInput[];
}) {
  const fetcher = useFetcher({key: "cart-increment"});
  
  useEffect(() => {
    console.log('fetcher.data', fetcher.data)
  }, [fetcher.data])

  return (
    <CartForm
      fetcherKey='cart-increment'
      route="/cart"
      action={CartForm.ACTIONS.LinesUpdate}
      inputs={{lines}}
    >
      {children}
    </CartForm>
  );
}
Helping merchants build super unique, high-performance storefronts using Weaverse + Hydrogen.
Looking for Development & Agency partners.
If you find the answer helpful, give it a thumbs up!
Our App: Theme Customizer for Shopify Hydrogen
Join our Weaverse + Hydrogen community: Weaverse Community
ajLonsway
New Member
4 0 0

That still won't work. The effect never updates, and fetcher from "cart-increment" is always '{"Form":{},"state":"idle"}', even when it fails to update.

Weaverse
Shopify Partner
82 27 38

Hmm, I think you can try this hook: https://github.com/Weaverse/pilot/blob/main/app/hooks/useCartFetchers.tsx

Helping merchants build super unique, high-performance storefronts using Weaverse + Hydrogen.
Looking for Development & Agency partners.
If you find the answer helpful, give it a thumbs up!
Our App: Theme Customizer for Shopify Hydrogen
Join our Weaverse + Hydrogen community: Weaverse Community
ajLonsway
New Member
4 0 0

It looks like I was checking the value of the fetcher through a console.log in the code, not in the returned JSX.Element. When I use the fetcher in the element, everything displays correctly.

 

const fetcher = useFetcher({key: 'cart-increment'});
  console.log(JSON.stringify(fetcher)); // "{"Form":{},"state":"idle"}"
  return (
    <CartForm
      route="/cart"
      action={CartForm.ACTIONS.LinesUpdate}
      fetcherKey="cart-increment"
      inputs={{lines}}
    >
      {/* {"Form":{},"state":"idle","data":{"cart":{"id":"gid://shopify/Cart/... */}
      <span>{JSON.stringify(fetcher)}</span>  
      {children}
    </CartForm>
  );

 

It looks like this gets the information that the form submits, but not necessarily the information we were looking for.

We're still trying to obtain the returning information from the Cart "Action". I don't know how to access and display this information on the front-end:

 

  return json(
    {
      cart: cartResult,
      errors,
      analytics: {
        cartId,
      },
    },
    {status, headers},
  );