Angular Shopping Cart with RxJS State Management
This challenge focuses on implementing a simple shopping cart application in Angular, utilizing RxJS for state management. Managing application state effectively is crucial for building scalable and maintainable Angular applications, and RxJS provides a powerful and reactive approach to achieve this. You will be building a basic shopping cart where users can add, remove, and view items.
Problem Description
You are tasked with creating an Angular component that displays a shopping cart and allows users to add and remove items. The shopping cart's state (items in the cart, total price) should be managed using RxJS Observables. The component should display the current items in the cart, their quantities, and the total price. Users should be able to add items to the cart and remove them. The UI should reactively update whenever the cart's state changes.
Key Requirements:
- State Management with RxJS: Use an RxJS BehaviorSubject to hold the shopping cart state. This state should include an array of cart items (each item having a
nameandprice) and the total price. - Component Interaction: The component should expose methods for adding and removing items from the cart.
- Reactive UI: The component's view should automatically update whenever the cart state changes.
- Initial State: The cart should initialize with an empty array of items and a total price of 0.
- Item Addition: Adding an item should add it to the cart (if it doesn't exist) or increment its quantity (if it already exists).
- Item Removal: Removing an item should remove it from the cart.
- Total Price Calculation: The total price should be dynamically calculated based on the items in the cart.
Expected Behavior:
- The component renders an empty cart initially.
- When an item is added, it appears in the cart with a quantity of 1.
- Adding the same item again increments its quantity.
- Removing an item removes it from the cart.
- The total price updates dynamically with each addition or removal.
- The UI remains responsive and reflects the current state of the cart.
Edge Cases to Consider:
- Handling invalid item data (e.g., negative prices). For simplicity, assume item data is always valid.
- Empty cart state.
- Removing an item that doesn't exist in the cart (should not cause errors).
Examples
Example 1:
Input: Initial state: []
Output: Cart displays: "Your Cart is Empty" and Total: $0.00
Explanation: The cart starts empty, so the UI reflects that.
Example 2:
Input: User adds "Apple" with price $1.00, then "Banana" with price $0.50.
Output: Cart displays:
- Apple x 1 - $1.00
- Banana x 1 - $0.50
Total: $1.50
Explanation: Two items are added, and the total price is calculated correctly.
Example 3:
Input: User adds "Apple" with price $1.00 twice, then removes "Apple".
Output: Cart displays:
- Apple x 2 - $2.00
Then, after removal:
- Apple x 1 - $1.00
Total: $1.00 (after adding twice) then $1.00 (after removing one)
Explanation: Demonstrates adding the same item multiple times and removing an item.
Constraints
- Angular Version: Use Angular 14 or higher.
- RxJS Version: Use RxJS 7 or higher.
- Component Size: Keep the component relatively concise and focused on the state management aspect. Avoid unnecessary UI complexity.
- Performance: The UI updates should be responsive even with a moderate number of items in the cart (e.g., up to 20 items). Avoid unnecessary re-renders.
- No External Libraries: Do not use external state management libraries like NgRx or Akita. The goal is to implement state management using RxJS directly.
Notes
- Consider using
scanoperator in RxJS to efficiently update the cart state and calculate the total price. - Think about how to structure your component's logic to keep it clean and maintainable.
- Focus on the reactive nature of RxJS and how it simplifies UI updates.
- You only need to implement the component and its associated state management logic. You don't need to create a full-fledged application with routing or other features. A simple HTML template to display the cart is sufficient.
- The
nameandpriceof the items are strings and numbers respectively.