Searching by name was one optional filter. A shop needs more: ?max_price=10, ?category=office, or several at once, joined with &. A request can send any mix of them, so no single fixed query fits: you build the query piece by piece.
Keep two arrays side by side. conditions, a string[], holds the pieces of the WHERE, each with a ?, and params, a (string | number)[], holds the values for those ?, in the same order. Give each empty array its type: TypeScript can't tell from [] what will go in it. The visitor's text only ever goes into params, so the query stays safe. At the end, .join(" AND ") glues the pieces with AND between them:
const pieces: string[] = ["year >= ?", "author = ?"];
console.log(pieces.join(" AND ")); // year >= ? AND author = ?
console.log([].join(" AND ")); // an empty string
Three dots spread an array into separate arguments: f(...[1990, "Ana"]) is the same as f(1990, "Ana"). That is how the values in params reach their ?, one value each.
Read max_price inside Number(...) to get a number; when the request has no max_price, the result is NaN. Test it with Number.isInteger(...), not just if (maxPrice): a maximum price of 0 is a real filter, but 0 counts as false in an if. name and category are read as string | undefined, and are undefined when the request doesn't send them.
GET /products?max_price=10 → 200 [{"id": 2, "name": "Notebook", …}, {"id": 4, "name": "Pen", …}, {"id": 7, "name": "Stapler", …}]
GET /products?category=home → 200 [{"id": 3, "name": "Lamp", …}, {"id": 5, "name": "Plant", …}]
GET /products?category=office&max_price=8 → 200 [{"id": 2, "name": "Notebook", …}, {"id": 4, "name": "Pen", …}]
GET /products?name=Teapot&category=kitchen → 200 [{"id": 6, "name": "Teapot", "price": 22, "category": "kitchen", "stock": 4}]
GET /products?name=Lamp&max_price=20 → 200 []
GET /products?max_price=0 → 200 []
GET /products?category=x' OR '1'='1 → 200 []
GET /products → 200 [… all 8 products …]
Your task: next to name, let GET /products take the optional filters max_price (products costing at most that much) and category. Build the WHERE from the filters the request really sends, with a ? placeholder for each value.
Assignment
Follow the Coding Tutorial to read the new filters, collect the conditions and their values, and run the query you built.
Hint
Push a condition and its value in the same if, so the two arrays stay in step. Declare sql with let, because it grows, and add " WHERE " only when the array of conditions isn't empty.
Free plan: 30 tutor messages. PRO is unlimited.
