This project puts most of what you have built so far into one new route. A product page shows the product's rating: the average of the stars in its reviews. The rating belongs to one product, so it gets a nested path under that product, just like the reviews: /products/1/rating.
An average in TypeScript: collect the numbers in an array of type number[], add them up with a loop, then divide the total by the array's length. Math.round(... * 100) / 100 keeps 2 decimal places, the way the /stats route does for the prices.
const temperatures: number[] = [20, 23, 22];
let total: number = 0;
for (const temperature of temperatures) {
total += temperature;
}
const average: number = Math.round((total / temperatures.length) * 100) / 100;
console.log(average); // 21.67
No numbers, no average: when the array is empty, its length is 0. In TypeScript, as in JavaScript, 0 divided by 0 doesn't crash: it gives NaN, "not a number". NaN is of type number, so the compiler doesn't warn you either, and JSON has no way to write it. So check for an empty array first and answer null, JSON's "no value". A product with no reviews still exists, so it gets 200 with a null rating. A product that isn't in products gets 404, as always.
The test requests, in this order, and what your code must answer:
GET /products/1/rating → 200 {"product_id": 1, "rating": 4.5}
GET /products/3/rating → 200 {"product_id": 3, "rating": 2}
GET /products/2/rating → 200 {"product_id": 2, "rating": null}
GET /products/99/rating → 404 {"error": "Product not found"}
POST /products/1/reviews {"stars": 5, "text": "My favourite mug"} → 201 (the review)
GET /products/1/rating → 200 {"product_id": 1, "rating": 4.67}
POST /products/2/reviews {"stars": 3, "text": "Thin pages"} → 201 (the review)
GET /products/2/rating → 200 {"product_id": 2, "rating": 3}
DELETE /products/3 → 204 (empty)
GET /products/3/rating → 404 {"error": "Product not found"}
Your task: just above the last line, app.use(notFound);, add a route for GET /products/:productId/rating. It answers the product_id and a rating: the average of the product's stars rounded to 2 places, or null when the product has no reviews. When no product has that id, it answers 404 with "Product not found".
Assignment
Follow the Coding Tutorial to add the /rating route just above app.use(notFound);: find the product, collect the stars of its reviews, and answer their rounded average, or a null rating when there are none.
Hint
Copy the shape of the GET route for the reviews to read the id, find the product and answer the 404 with errorResponse, and the shape of the /stats route for the number[] array, the empty check and the rounded average. Check for an empty array before you divide.
Free plan: 30 tutor messages. PRO is unlimited.
