Practice: JavaScript for React — Product Review Interface

Building the frontend foundation for Multi-Source Product Review Aggregator

Practice
JavaScript
DOM
Async
AI-Assisted Development
Auteur
Affiliations

Université de Toulon

LIS UMR CNRS 7020

Date de publication

2025-10-12

Résumé

Course lectures and practices for JavaScript full‑stack web development with AI‑assisted workflows.

Overview — Focused Practice

Philosophy: Build the core skills, skip the complex parts (React will handle them better).

Goal: Build essential JavaScript skills for our Multi-Source Product Review Aggregator:

Core Steps : - Step 1: Static product data → DOM rendering - Step 2: Add basic review filtering - Step 3: Replace with fetch() API

Optional Steps (if time permits): - Step 4: Add search + multiple filters (Optional) - Step 5: Polish + error handling (Optional)

Project Context: This practice builds the JavaScript foundation you’ll need when we convert everything to React in Session 3.

Objectives

By the end you should be able to:

  • Render product data to DOM using JavaScript
  • Handle user events (clicks, input changes)
  • Filter arrays with JavaScript
  • Use fetch() with async/await
  • Debug with browser DevTools
  • Apply these skills to build React components for our review aggregator

Prerequisites

  • Completed Lecture: JavaScript for React
  • Basic HTML/CSS skills
  • VS Code with Live Server extension

Setup & Running the Frontend

File Setup

Create these files in fullstack-minimal-app/frontend/public/prototypes/:

  • product-reviews-interface.html — main page
  • product-reviews-interface.js — all JavaScript code

Live Server Setup

Avertissement

Browsers block fetch() when opening files via file://. You need to use VS Code’s Live Server extension for local development.

Setup Steps:

  1. Install Live Server Extension (if not already installed)
    • Open VS Code
    • Go to Extensions (Ctrl+Shift+X / Cmd+Shift+X)
    • Search for “Live Server” by Ritwick Dey
    • Click Install
  2. Open and Serve Your Files
    • Open the folder fullstack-minimal-app/frontend/public/prototypes in VS Code
    • Right-click on product-reviews-interface.html → “Open with Live Server”
    • Your browser will automatically open the page (typically at http://127.0.0.1:5500/product-reviews-interface.html)
    • Live Server will auto-reload the page when you save changes

Troubleshooting:

  • If fetch() returns CORS or network errors, confirm you’re using the Live Server URL (http://127.0.0.1:5500) not file://
  • If port 5500 is in use, Live Server will automatically pick another port
  • If the page doesn’t auto-reload on save, ensure the workspace folder contains your files
  • Make sure all files are saved in the same folder that Live Server is servingi

Security Note: Live Server is for local development only. Do not expose it publicly without proper security.

Step 1: Static Data + Basic Rendering

Goal: Start with hardcoded product data including review summaries, render product cards to DOM.

1.1: Create HTML Shell (MINIMAL)

Prompt for AI:

Create product-reviews-interface.html for our Multi-Source Product Review Aggregator with:
1. Header: "Multi-Source Product Review Aggregator" 
2. Subheader: "Compare reviews from Amazon, BestBuy, Walmart"
3. Empty div with id="product-grid" for products
4. Include Tailwind CDN for styling
5. Include <script src="product-reviews-interface.js"></script> at end
6. Simple grid layout (CSS Grid or Flexbox)

Keep it minimal - no filters yet, just the container for products with review data.

1.2: Add Static Data + Render Function (MINIMAL)

Prompt for AI:

Create product-reviews-interface.js with:

1. Static array of 4-5 products with review aggregation data:
const products = [
  {
    id: "prod-001", 
    name: "Wireless Bluetooth Headphones", 
    category: "Electronics",
    avgRating: 4.2,
    totalReviews: 156,
    sources: ["Amazon", "BestBuy", "Walmart"],
    reviewBreakdown: {
      "Amazon": {avgRating: 4.3, count: 89},
      "BestBuy": {avgRating: 4.0, count: 45},
      "Walmart": {avgRating: 4.4, count: 22}
    }
  },
  // ... 3-4 more products with similar structure
];

2. Function renderProducts(productsArray) that:
   - Clears the product-grid
   - Loops through products
   - Creates HTML for each product using template literals
   - Shows product name, average rating, total reviews, and source breakdown
   - Inserts into DOM using innerHTML

3. Function init() that:
   - Waits for DOMContentLoaded
   - Calls renderProducts(products)

4. Call init() at the end

Focus on displaying product cards with review aggregation data first.

Test: Products with review summaries should display when you open the page!

1.3: Improve Product Cards (Optional)

Prompt for AI:

Enhance the product cards to show:
- Product image (use https://placehold.co/300x200?text=ProductName)
- Product name and category
- Overall average rating with stars (★★★★☆ format)
- Total review count ("156 reviews from 3 sources")
- Source breakdown table showing each platform's rating
- Button "View All Reviews" (placeholder for now)
- Button "Fetch Fresh Reviews" (simulates our aggregator's core feature)

Use Tailwind classes for professional styling. Make cards look like a real review aggregator interface.

✅ Checkpoint: You should see professional product cards with review aggregation data.

Step 2: Add Basic Source Filter

Goal: Filter products by review source (Amazon, BestBuy, Walmart) to learn the pattern.

2.1: Add Filter UI (MINIMAL)

Add to HTML (update product-reviews-interface.html):

<!-- Add this before product-grid -->
<div class="mb-6 p-4 bg-gray-50 rounded-lg">
  <h3 class="text-lg font-semibold mb-4">Filter Products</h3>
  <div class="mb-4">
    <label for="source-filter" class="block text-sm font-medium mb-2">Review Source:</label>
    <select id="source-filter" class="border rounded px-3 py-2">
      <option value="all">All Sources</option>
      <option value="Amazon">Amazon Reviews</option>
      <option value="BestBuy">BestBuy Reviews</option>
      <option value="Walmart">Walmart Reviews</option>
    </select>
  </div>
</div>

2.2: Add Filtering Logic (MINIMAL)

Prompt for AI:

Update product-reviews-interface.js to add source filtering:

1. Add filterProductsBySource(products, source) function that:
   - Returns all products if source === 'all'
   - Returns products that have reviews from the specific source
   - Uses array.filter() and checks if source exists in product.sources array

2. Update init() to add event listener:
   - Get source-filter element
   - Listen for 'change' event
   - Get selected value
   - Call filterProductsBySource() with current value
   - Call renderProducts() with filtered results

3. Test with console.log to see filtering working

This simulates filtering products based on which review sources have data for them.

✅ Checkpoint: Source dropdown should filter products correctly.

2.3: Add Results Count (Optional)

Prompt for AI:

Add a results counter for our review aggregator:

1. Add HTML element for results count: "Showing X of Y products with reviews"
2. Create updateResultsCount(shown, total) function
3. Call it after filtering
4. Update display text to include review context

Step 3: Replace Static Data with Fetch

Goal: Replace hardcoded array with real JSON file and fetch() - simulating our backend API.

3.1: Create JSON File (MINIMAL)

Create products-with-reviews.json:

{
  "products": [
    {
      "id": "prod-001",
      "name": "Wireless Bluetooth Headphones",
      "category": "Electronics",
      "avgRating": 4.2,
      "totalReviews": 156,
      "sources": ["Amazon", "BestBuy", "Walmart"],
      "reviewBreakdown": {
        "Amazon": {"avgRating": 4.3, "count": 89},
        "BestBuy": {"avgRating": 4.0, "count": 45},
        "Walmart": {"avgRating": 4.4, "count": 22}
      }
    },
    {
      "id": "prod-002",
      "name": "4K Webcam",
      "category": "Electronics",
      "avgRating": 3.8,
      "totalReviews": 234,
      "sources": ["Amazon", "BestBuy"],
      "reviewBreakdown": {
        "Amazon": {"avgRating": 3.9, "count": 198},
        "BestBuy": {"avgRating": 3.6, "count": 36}
      }
    },
    {
      "id": "prod-003",
      "name": "USB-C Charging Cable",
      "category": "Accessories",
      "avgRating": 4.6,
      "totalReviews": 89,
      "sources": ["Amazon", "Walmart"],
      "reviewBreakdown": {
        "Amazon": {"avgRating": 4.5, "count": 67},
        "Walmart": {"avgRating": 4.8, "count": 22}
      }
    },
    {
      "id": "prod-004",
      "name": "Mechanical Keyboard",
      "category": "Electronics",
      "avgRating": 4.4,
      "totalReviews": 312,
      "sources": ["Amazon", "BestBuy", "Walmart"],
      "reviewBreakdown": {
        "Amazon": {"avgRating": 4.5, "count": 198},
        "BestBuy": {"avgRating": 4.2, "count": 87},
        "Walmart": {"avgRating": 4.6, "count": 27}
      }
    }
  ]
}

3.2: Replace Static Data with Fetch (MINIMAL)

Prompt for AI:

Update product-reviews-interface.js to use fetch() (simulating our backend API):

1. Remove the static products array

2. Create async function fetchProducts() that:
   - Fetches './products-with-reviews.json'
   - Checks response.ok
   - Parses JSON with response.json()
   - Returns data.products
   - Includes try/catch error handling

3. Update init() function to:
   - Call fetchProducts() instead of using static data
   - Wait for products to load before setting up filters
   - Handle loading state (show "Loading product reviews..." message)

4. Make sure Live Server is running (needed for fetch to work)

Use async/await syntax from the lecture. This simulates calling our backend API for aggregated review data.

✅ Checkpoint: Products with review data should load from JSON file via fetch.


🎯 Core Practice Complete!

At this point, you have accomplished the essential learning objectives: - ✅ DOM manipulation with JavaScript - ✅ Event handling and user interaction
- ✅ Array filtering and data transformation - ✅ Async/await with fetch API - ✅ Ready for React in Session 3!

The optional steps below provide additional practice but aren’t required.


📚 Optional Extensions

Optional Steps - Only if Time Permits

These steps provide additional practice but are not required for Session 3 preparation.

Priority: Understanding the concepts above is more important than completing every step.

Step 4: Add More Filters (Optional)

Goal: Add search and rating filters to practice multiple filters.

4.1: Add Search Filter (Optional)

Add to HTML:

<div class="mb-4">
  <label for="search-input" class="block text-sm font-medium mb-2">Search Products:</label>
  <input type="text" id="search-input" placeholder="Search products..." 
         class="border rounded px-3 py-2 w-full">
</div>

Prompt for AI:

Add product search functionality for our review aggregator:

1. Add searchProducts(products, query) function that:
   - Returns all products if query is empty
   - Filters products where name includes query (case-insensitive)
   - Uses product.name.toLowerCase().includes(query.toLowerCase())

2. Update filtering to handle both source AND search:
   - Create applyAllFilters() function
   - Apply source filter first, then search filter
   - Chain the filters: searchProducts(filterProductsBySource(products, source), query)

3. Add search input event listener (use 'input' event)
4. Update both dropdowns and search to call applyAllFilters()

4.2: Add Rating Filter (Optional)

Add to HTML:

<div class="mb-4">
  <label for="min-rating" class="block text-sm font-medium mb-2">Minimum Rating:</label>
  <select id="min-rating" class="border rounded px-3 py-2">
    <option value="0">All Ratings</option>
    <option value="3">3+ Stars</option>
    <option value="4">4+ Stars</option>
    <option value="4.5">4.5+ Stars</option>
  </select>
</div>

Prompt for AI:

Add rating filtering for our review aggregator:

1. Add filterByRating(products, minRating) function that filters by avgRating
2. Update applyAllFilters() to chain all three filters
3. Add event listener for rating select
4. Parse rating values with parseFloat()

This helps users find highly-rated products across all review sources.

✅ Checkpoint: All three filters should work together.

Step 5: Polish + Error Handling (Optional)

5.1: Add Loading State (Optional)

Add to HTML:

<div id="loading" class="text-center py-8 hidden">
  <div class="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
  <p class="text-gray-500 mt-2">Loading product reviews from multiple sources...</p>
</div>

Prompt for AI:

Add proper loading states for our review aggregator:

1. Show loading message while fetching product review data
2. Hide loading message when done
3. Show error message if fetch fails
4. Add empty state when no products match filters ("No products found with selected criteria")

5.2: Add Reset Button (Optional)

Add to HTML:

<button id="reset-filters" class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">
  Reset All Filters
</button>

Prompt for AI:

Add reset functionality for our review aggregator:
1. Clears all filter inputs (source, search, rating)
2. Resets to show all products
3. Updates results count
4. Provides good UX for exploring different filter combinations

5.3: Connect to Real Scraper Service (Advanced Optional)

Real Scraper Integration

This section demonstrates connecting to the actual scraper service mentioned in our Multi-Source Product Review Aggregator project. Only attempt this if:

  • You have the scraper service running (provided separately)
  • You want to see real review aggregation in action
  • You’re comfortable with cross-origin requests

Skip this section if you just want to focus on JavaScript fundamentals.

Prerequisites for this section: - Scraper service running on http://localhost:3001 - Understanding that this previews our full-stack integration

Prompt for AI:

Replace the simulated "Fetch Fresh Reviews" with real scraper integration:

1. Update the fetch button handler to call the real scraper API:
   - POST to http://localhost:3001/api/scrape
   - Send product ID in request body: {productId: "prod-001"}
   - Handle CORS by running scraper with proper headers

2. Process the real response data:
   - Extract reviews from multiple sources (Amazon, BestBuy, Walmart)
   - Calculate new aggregated statistics
   - Update the product card with fresh data

3. Add proper error handling:
   - Network errors (scraper offline)
   - Invalid responses
   - Rate limiting messages

4. Show realistic loading states:
   - "Fetching from Amazon..."
   - "Fetching from BestBuy..."  
   - "Aggregating results..."

Example API call structure:
```javascript
const response = await fetch('http://localhost:3001/api/scrape', {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({productId: product.id})
});

This gives you a preview of how our frontend will integrate with the backend scraper service in Practice 4-6! ```

What this demonstrates: - Real API integration patterns - Handling asynchronous external service calls - Data transformation and aggregation - Error handling for network requests - The complete review aggregation workflow

✅ Advanced Checkpoint: Real reviews fetched and aggregated from multiple sources.

✅ Final Checkpoint: Complete working product review interface with realistic aggregator features.

Connection to Our Multi-Source Review Aggregator

What you just built is the foundation for our review aggregator’s frontend:

  • Product cards → will show real aggregated review data from our backend
  • Source filtering → will filter by which platforms have reviews
  • Search & rating filters → will help users find products meeting their criteria
  • Fetch functionality → will become real API calls to our Node.js backend
  • Dynamic updates → will reflect real-time review aggregation

In React (Practice 3), you’ll convert this vanilla JavaScript into: - ProductCard component - FilterPanel component
- useProducts hook for data fetching - State management for filters and loading states

Testing Checklist

Minimal Features: - [ ] Products with review data render from static data - [ ] Products load from JSON via fetch - [ ] Source filter works (Amazon/BestBuy/Walmart) - [ ] Basic error handling works

Optional Features: - [ ] Search filter works (case-insensitive) - [ ] Rating filter works (3+, 4+, 4.5+ stars) - [ ] Multiple filters work together - [ ] Results count updates with review context - [ ] Reset button clears everything - [ ] Loading state shows/hides with review messaging - [ ] “Fetch Fresh Reviews” simulation works

Why This Prepares You for React

This progressive approach teaches you exactly what React will simplify: - Manual DOM manipulation → React’s declarative rendering - Event listener management → React’s event handling - State synchronization → React’s state management - Component organization → React’s component model

Next session: Convert this product review interface to React components and see the dramatic improvement in code organization and maintainability!

Réutilisation