#Initialize a shopping cart cookie AND update the cart within the same action

1 messages · Page 1 of 1 (latest)

pure timber
#

If my shopping cart does not exist, I first initialize the cart via a POST endpoint. This requires creating a cart cookie which has to be returned in the response for the cookie to be set in the browser.

In the case of creating a new cart cookie, I never reach the code to update the cart due to the return. Is there a way to create the cart cookie without the return statement in the action?

export async function action({ params ,request }: ActionArgs) {

  let cartId = await getCartCookie(request)

  // if no cart cookie, create the cookie
  if(!cartId) {
    const cartCookie = await createCartCookie(request)

    // to create the cookie here, we need to return it. Can this be avoided?
    return cartCookie
  }
  
  // else, cart cookie exists. Update cart with cartId
  const { product } = await client.products.retrieve(params.productId);
  const variant_id = product.variants[0].id

  const { cart }= await client.carts.lineItems.create(cartId, {
      variant_id,
      quantity: 1,
    })

  return cart.items
};
mental ginkgo
#

What does createCartCookie return? Is it just a response with a header set? If so, you could return the set cookie header and then just add it to the update response instead (you can use the json helper to make this easier)

#

e.g.

export async function action({ params ,request }: ActionArgs) {

  let cartId = await getCartCookie(request)

  const headers = new Headers();

  // if no cart cookie, create the cookie
  if(!cartId) {
    const cartCookieHeaders = await createCartCookie(request)

    headers = new Headers({
      // Copy over any other headers you may want to set
      ...headers,
      ...cartCookieHeaders,
    });
  }
  
  // else, cart cookie exists. Update cart with cartId
  const { product } = await client.products.retrieve(params.productId);
  const variant_id = product.variants[0].id

  const { cart }= await client.carts.lineItems.create(cartId, {
      variant_id,
      quantity: 1,
    })

  return json(cart.items, {
    headers,
  });
};
#

Or, if you can't change the createCartCookie function, assuming it returns a Response.

if(!cartId) {
    const cartCookie = await createCartCookie(request)

    headers = new Headers({
      // Copy over any other headers you may want to set
      ...headers,
      ...cartCookie.headers,
    });
}
pure timber
#

Thank you!

createCartCookie returns json with a header set like this

  return json(cart.id, {
    headers: {
      "Set-Cookie": await cartCookie.serialize({
        cartId: cart.id,
      }),
    },
  });

Looks like I can go with the first option proposed

I'd like to extract cart.id from createCartCookie. For some reason, I don't see it anywhere when logging the response from createCartCookie. This is needed to make the next call to create the line item with quantity in the cart.

mental ginkgo
#

In that case, you can still return the json response, use Response.headers for the set cookie header, and the cart id by reading the body, or you could return an object from the create function with the properties of cartId and headers if you prefer