Between opening the cart and clicking Pay, the world can change: another shopper may buy the last items first. The API then refuses the checkout with 409 Conflict, which means the request clashes with the data as it is now. Its JSON has the error message and the product_id of the product that is short, and nothing is charged.
The given checkout page catches the 409 and sends the visitor to the cart with both values in the navigation's state. The cart page reads it with useLocation(): location.state holds productId and message, or null when the visitor came by a plain link.
To mark the right line, the page needs an object whose key is a product id it only knows at run time. Square brackets around a key use a variable's value as the key:
const field = "email";
const errors = { [field]: "Required" }; // { email: "Required" }
In the check, Ana has a Mug and 3 Teapots ($78). Before she pays, Ben buys 2 Teapots, and only 2 are left. The check must print:
> click "Pay"
request: POST /api/checkout {…} -> 409
request: GET /api/cart -> 200
item: Teapot × 3 $66
alert: Only 2 Teapot left
GET /payments
200
[{"amount": 44, "id": "pay_1", "order_id": null, "status": "succeeded"}]
> click "−" in "Teapot"
request: PUT /api/cart/6 {"quantity": 2} -> 200
- item: Teapot × 3 $66
+ item: Teapot × 2 $44
- alert: Only 2 Teapot left
The only payment is Ben's $44: Ana was never charged.
Your task: in client/src/pages/CartPage.jsx, take location from useLocation() and add an effect that runs again when location.state changes. When there is a state, call tryAgain() to load the cart from the server, and set errors to an object with the key location.state.productId and the value location.state.message.
Assignment
Follow the Coding Tutorial to make the cart page react to a 409: reload the cart and show the server's message on the line that is short.
Hint
Put location.state in the effect's dependency list, and check it with an if before you use it. The cart's lines already show errors[item.product_id] when it has a message.
Free plan: 30 tutor messages. PRO is unlimited.
