Hone logo
Hone
Problems

Dynamic Product Filtering in an Angular E-commerce App

This challenge requires you to implement a robust filtering mechanism for a list of products in an Angular application. This is a fundamental feature for any e-commerce platform, allowing users to quickly narrow down their choices based on various criteria, improving user experience and conversion rates.

Problem Description

You are tasked with building a product listing component in Angular that displays a list of products. Users should be able to filter this list dynamically based on several criteria: product category, price range, and availability (in stock or out of stock).

Key Requirements:

  1. Display Products: The component should fetch and display a list of products. Each product should have at least the following properties: id (number), name (string), category (string), price (number), and inStock (boolean).
  2. Filtering Controls: Implement UI controls (e.g., dropdowns, checkboxes, sliders) for users to select filtering criteria.
    • Category Filter: A dropdown or multi-select to choose one or more product categories.
    • Price Range Filter: A mechanism to specify a minimum and maximum price (e.g., two input fields or a range slider).
    • Availability Filter: A checkbox or toggle to filter for products that are inStock.
  3. Dynamic Filtering: As users interact with the filtering controls, the displayed product list should update in real-time to show only products that match all selected criteria.
  4. Clear Filters: Provide a button to reset all filters and display the full product list.
  5. No External Libraries (for filtering logic): The filtering logic itself should be implemented using Angular's reactive programming capabilities (e.g., RxJS Observables) and TypeScript, not third-party filtering libraries.

Expected Behavior:

  • When the component loads, all products should be displayed.
  • Selecting a category should immediately update the product list to show only products from that category.
  • Adjusting the price range should filter the list accordingly.
  • Toggling the "In Stock" filter should show or hide out-of-stock items.
  • Applying multiple filters simultaneously should result in a list of products that satisfy all conditions.
  • Clicking "Clear Filters" should revert the display to show all products.

Edge Cases to Consider:

  • What happens if no products match the selected filters? The list should be empty, and ideally, a message should inform the user.
  • How to handle initial loading of products while filters are being applied?
  • What if a user selects multiple categories?
  • How to ensure the price range filtering handles valid number inputs and potential errors?

Examples

Example 1: Initial Load

Input: A predefined list of products (e.g., 5-10 products with varying categories, prices, and stock status).

Output: All products from the predefined list are displayed.

Explanation: On component initialization, no filters are applied, so the complete dataset is rendered.

Example 2: Category and Price Filtering

Input:

  • Predefined Products:
    [
        {"id": 1, "name": "Laptop Pro", "category": "Electronics", "price": 1200, "inStock": true},
        {"id": 2, "name": "Mechanical Keyboard", "category": "Electronics", "price": 150, "inStock": true},
        {"id": 3, "name": "Gaming Mouse", "category": "Electronics", "price": 75, "inStock": false},
        {"id": 4, "name": "T-Shirt", "category": "Apparel", "price": 25, "inStock": true},
        {"id": 5, "name": "Jeans", "category": "Apparel", "price": 60, "inStock": true}
    ]
    
  • User Actions:
    • Selects "Electronics" from the category filter.
    • Sets the price range from $100 to $1500.

Output:

[
    {"id": 1, "name": "Laptop Pro", "category": "Electronics", "price": 1200, "inStock": true},
    {"id": 2, "name": "Mechanical Keyboard", "category": "Electronics", "price": 150, "inStock": true}
]

Explanation: The list is filtered to include only products in the "Electronics" category. Among those, only products with prices between $100 and $1500 (inclusive) are displayed. The "Gaming Mouse" is excluded because it's out of stock, and the "Mechanical Keyboard" and "Laptop Pro" are included because they meet both criteria.

Example 3: Availability and Price Filtering (Edge Case: No Results)

Input:

  • Predefined Products: (Same as Example 2)
  • User Actions:
    • Checks the "In Stock Only" filter.
    • Sets the price range from $0 to $50.

Output: An empty list, with a message like "No products found matching your criteria."

Explanation: After applying the filters, no products from the list are both in stock AND priced between $0 and $50. The "Gaming Mouse" is excluded due to being out of stock. The "T-Shirt" is in stock but costs $25, which is within the range. The "Jeans" are in stock but cost $60, outside the range. Therefore, only the T-Shirt should appear. Let's re-evaluate the example for no results.

Example 3 (Revised): Availability and Price Filtering (No Results Scenario)

Input:

  • Predefined Products:
    [
        {"id": 1, "name": "Laptop Pro", "category": "Electronics", "price": 1200, "inStock": true},
        {"id": 2, "name": "Mechanical Keyboard", "category": "Electronics", "price": 150, "inStock": true},
        {"id": 3, "name": "Gaming Mouse", "category": "Electronics", "price": 75, "inStock": false},
        {"id": 4, "name": "T-Shirt", "category": "Apparel", "price": 25, "inStock": true},
        {"id": 5, "name": "Jeans", "category": "Apparel", "price": 60, "inStock": true}
    ]
    
  • User Actions:
    • Checks the "In Stock Only" filter.
    • Sets the price range from $500 to $800.

Output: An empty list, with a message like "No products found matching your criteria."

Explanation: The "In Stock Only" filter is applied. Then, the price range is set to $500-$800. None of the in-stock products ("Laptop Pro", "Mechanical Keyboard", "T-Shirt", "Jeans") fall within this specific price range, resulting in an empty filtered list.

Constraints

  • The product list will contain a minimum of 10 products and a maximum of 100 products.
  • Product prices will be between 1 and 5000 (inclusive).
  • Product names, categories, and IDs will be unique.
  • The filtering operation should update the UI within 200ms for typical user interactions on modern hardware.
  • The solution should be implemented within a single Angular component.

Notes

  • Consider using Angular's OnPush change detection strategy for performance optimization.
  • RxJS combineLatest or similar operators can be very useful for managing multiple filter streams.
  • Think about how to structure your component's state to hold filter values and the filtered product list.
  • You can simulate fetching products using a simple array or a service that returns an Observable of products.
Loading editor...
typescript