Skip to content

Cart ​

A headless shopping cart implementation using Recoil.

Overview ​

Cart is based off of a git branch model and has 3 main states, staged, cart and items.

staged ​

staged is where the current product the user is editing is stored. This product is preformatted to include actions such as add, remove and select.

cart ​

cart is the main branch that staged products get comitted to. cart also comes with actions.

items ​

items is the final master branch that is trimmed to include only critical information (no display data). This is what we send to all other services (APIs, SDKs etc).

Usage ​

The useCart hook returns 5 items.

js
const { stage, staged, commit, cart, items } = useCart();

stage ​

js
const { stage } = useCart();

stage({ product }); // Product must be a fully hydrated menu product

staged ​

js
const { staged } = useCart();

console.log(staged);
// {
//     id: 30456,
//     price: 1600,
//     selected: true,
//     uid: "sj234ifeuj8s",
//     name: { text: "Burger" },
//     imageUrl: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
//     count: { current: 1, min: 0, max: 0 },
//     add () => {},
//     remove: () => {},
//     select: () => {},
//     options: [...],
//     customisations: [...],
// }

commit ​

js
const { commit } = useCart();

commit(); // moves and appends `staged` to `cart`

cart ​

js
const { cart } = useCart();

console.log(cart); // array of actionable products (see `staged` for example)

items ​

js
const { items } = useCart();

console.log(items);
//  [
//    {
//         "id": "30733",
//         "price": 13.95,
//         "quantity": 1,
//         "product": {
//           "id": "30733",
//           "type": "combo",
//           "price": 11.45,
//           "name": "Zinger Burger Box",
//           "customisations": [
//             {
//               "productId": "554357",
//               "categoryId": "90115",
//               "name": "Lettuce",
//               "price": 0,
//               "defaultQuantity": 1,
//               "quantity": 1,
//               "providerData": {
//                 "DefaultReason": 1,
//                 "ModifierAction": 0
//               }
//             }
//           ],
//           "comboProducts": [
//             {
//               "id": "40956",
//               "name": "Zinger Burger",
//               "price": 5.95,
//               "customisations": [],
//               "providerData": {}
//             }
//           ],
//           "providerData": {
//             "PromoId": 4002,
//             "MenuItemId": 30733,
//             "SalesItemId": 0
//           }
//         }
//       }
// ]

Lifecycle ​

The current lifecycle for a hydrated product (product that is passed into stage) to a trimmed product (items) is as follows.

  • Product is formatted to include minimal display information and self updating functions (see notes for more).
  • Product is added to staged

If a user actions a staged product

  • The entire product tree is traversed and changes are made to product based on uid
  • The current tree is replaced by the new, updated tree
  • The tree is re-evaluated for new display information (count updates etc)

When the staged product is commited

  • The staged product is reformatted to include the correct update functions (cart setter instead of staged setter)
  • The staged product is appended to the cart
  • Recoil selector trims the cart and produces items