Start learning free

LESSON 164 OF 173 · BACKEND: BACKEND WITH AI

A Shared Default

Practice

The shop keeps each customer's cart in the object carts, and its routes make new carts with makeCart: {"owner": "ana", "items": []}. The items parameter lets the PUT route bring back a saved cart; without it, a cart starts empty. An AI assistant wrote it like this:

const noItems: string[] = [];

function makeCart(owner: string, items: string[] = noItems): Cart {
  return { owner: owner, items: items };
}

Then Ben added a pen and found Ana's mug in his cart. A line at the top of the file runs once, when the app starts, not at each call. So every cart made without items gets that same one array, and what one customer adds, every customer sees. This is a shared default. The types are all correct, so TypeScript doesn't complain. A smaller example:

const tags: string[] = [];

function addTag(tag: string, list: string[] = tags): string[] {
  list.push(tag);
  return list;
}

console.log(addTag("new"));    // [ 'new' ]
console.log(addTag("sale"));   // [ 'new', 'sale' ]: the same array again

The fix: give items no default, and mark it optional with a ? after its name, so a call may still leave it out. A call that does gets undefined, and undefined can't be changed, so sharing it is harmless. Then, inside the function, make a new empty array when the value is undefined: lines inside a function run at every call, so every call gets an array of its own. An array that was passed in, like a restored cart, is kept as it is.

Your rewrite must give these answers:

POST /carts/ana/items  {"product": "Mug"}   →  201  {"owner": "ana", "items": ["Mug"]}
POST /carts/ben/items  {"product": "Pen"}   →  201  {"owner": "ben", "items": ["Pen"]}
POST /carts/ana/items  {"product": "Lamp"}  →  201  {"owner": "ana", "items": ["Mug", "Lamp"]}
GET  /carts/ben                             →  200  {"owner": "ben", "items": ["Pen"]}
GET  /carts/eva                             →  200  {"owner": "eva", "items": []}
PUT  /carts/chloe  {"items": ["Plant", "Teapot"]}  →  200  {"owner": "chloe", "items": ["Plant", "Teapot"]}

Your task: rewrite makeCart so a cart made without items gets a new empty array of its own, and a cart made with items keeps that array.


Assignment
Follow the Coding Tutorial to rewrite makeCart with an optional items that has no default, and a new array made inside the function.


Hint
Write the parameter as items?: string[]. The new array must be made inside the function, below the function line, so it runs at every call. Check with items === undefined. Until the return is written, tsc reports that a function typed : Cart must return a value. When AI code keeps an array or an object in one constant and hands it out as a default value, ask whether every call shares it.


STEP 1 OF 4
    Ctrl + Enter to check