Next.js Discord

Discord Forum

Getting a cart from cart_cookie and passing it to client components.

Unanswered
Masai Lion posted this in #help-forum
Open in Discord
Avatar
Masai LionOP
Hello everyone ๐Ÿ™‚

I am using medusa-js to develop a store, and I am trying to write my custom logic for creating cart. I have a file actions.cart.ts with a "use server" directive at the top. I created a couple of functions for sending api requests to my backend to create or get a cart depending on if it exists. I create a _medusa_cart_id cookie which stores the cart_id succesfuly.

export async function createCart() {
  try {
    const res = await fetch(`${MEDUSA_BACKEND_URL}/store/carts`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      next: {
        tags: ['cart']
      },
      cache: 'no-store'
    });

    console.log('Cart creation response', res);

    const data = await res.json();
    if (res.status === 200) {
      const cart = data.cart;

      const cookieStore = cookies();

      cookieStore.set('_medusa_cart_id', cart.id, {
        maxAge: 60 * 60 * 24 * 7,
        httpOnly: true,
        sameSite: 'strict',
        secure: process.env.NODE_ENV === 'production'
      });

      console.log('Cart created', cart);
      revalidateTag('cart');
      return cart as Cart;
    } else {
      throw new Error('Failed to create cart');
    }
  } catch (error) {
    console.log(`Error creating cart: ${error}`);
  }
}


When I add products they are succesfuly added in the backend. However, I can't for the love of god figure out how to get the cart object and pass it to further components, specifically my <Header /> and <CartPopover />. Header is a server component, and the cart popover is a client component.

2 Replies

Avatar
Masai LionOP
I created a getCart function to get the cart:

export async function getCart() {
  const cartId = cookies().get('_medusa_cart_id')?.value;

  console.log('Cart ID from the cookie', cartId);

  if (!cartId) {
    console.log('No cart ID found');
    return null;
  }

  const response = await fetch(`${MEDUSA_BACKEND_URL}/store/carts/${cartId}`, {
    method: 'GET',
    next: {
      tags: ['cart']
    },
    cache: 'no-store'
  });
  const data = await response.json();

  if (response.status === 200) {
    const cart = data.cart;
    return cart as Cart;
  } else {
    console.log('Failed to get cart');
    return null;
  }
}

And I made this little helper to getOrSet the cart if it doesn't exist:

export async function getOrSetCart2() {
  const cartId = cookies().get('_medusa_cart_id')?.value;

  let cart;

  if (cartId) {
    console.log('Getting cart from cookie', cartId);
    cart = await getCart().then((res) => res);
  }

  if (!cart) {
    console.log('Creating new cart');
    cart = await createCart();
    if (cart) {
      // revalidateTag('cart');
    }
  }
  return cart as Cart;
}
In my Header component (mounted in my layer.tsx) I am awaiting the getCart function to get the cart and then passing it to the CartPopover client component to display some info about the items in the cart:

'use server';
import { getCart } from '@/actions/actions.cart';
import CartPopover from '@/components/popovers/CartPopover';
import DesktopMenu from '../navigation/DesktopMenu';
import MobileMenu from '../navigation/MobileMenu';

export default async function Header() {
  const cart = await getCart();

  console.log('Cart fetched in Header:', cart);

  return (
    <header className="sticky top-0 z-50 w-full bg-background shadow-sm shadow-gray-900/10">
      <div className="container relative mx-auto flex min-h-20 flex-row items-center justify-start gap-4 lg:min-h-10 lg:justify-center">
        <div className="hidden w-full lg:block">
          <DesktopMenu cart={cart} />
        </div>
        <div className="flex w-full justify-between bg-background lg:hidden">
          <div>
            <MobileMenu />
          </div>
          <div className="flex items-center gap-6">
            <CartPopover cart={cart} />
          </div>
        </div>
      </div>
    </header>
  );
}




But the cart always console logs to null
Cart fetched in Header: null, even if the cookie gets set and the items get added....

What am I doing wrong? Sorry for the long post ๐Ÿ˜