Hone logo
Hone
Problems

Angular Scoped Service Implementation

This challenge focuses on understanding and implementing scoped services in Angular. Scoped services are crucial for managing state and behavior within specific parts of your application, such as a particular component or a section of the UI. You'll create a service that provides unique instances to different parts of the component tree, allowing for isolated data management.

Problem Description

Your task is to create a CounterService that can be scoped to a specific component. This means that when the CounterService is provided at the root level, each component requesting it will get the same instance (singleton). However, when provided at a component's level, each instance of that component (and its children) should receive its own distinct CounterService instance.

Key Requirements:

  1. CounterService:
    • Must have a count property, initialized to 0.
    • Must have an increment() method that increases count by 1.
    • Must have a decrement() method that decreases count by 1.
    • Must have a getCount() method that returns the current count.
  2. AppComponent (Root Component):
    • Should inject the CounterService.
    • Should display the count from the root-level service.
    • Should have a button to increment the root service's count.
    • Should render a child component (ScopedCounterComponent) twice.
  3. ScopedCounterComponent:
    • Should inject the CounterService.
    • This injection must be scoped to this component. This means the CounterService should be provided in the providers array of the ScopedCounterComponent decorator.
    • Each instance of ScopedCounterComponent should display its own independent count.
    • Each instance should have buttons to increment and decrement its own scoped service's count.

Expected Behavior:

  • The AppComponent displays a count. When its increment button is clicked, this count increases.
  • Both instances of ScopedCounterComponent display their own initial count of 0.
  • Clicking the increment/decrement buttons on the first ScopedCounterComponent only affects its count.
  • Clicking the increment/decrement buttons on the second ScopedCounterComponent only affects its count.
  • The counts displayed by the ScopedCounterComponent instances are independent of each other and of the AppComponent's count.

Edge Cases to Consider:

  • Ensuring the service is correctly provided at the component level and not inadvertently at the root level for the scoped instances.

Examples

Example 1: Initial State

  • AppComponent Display: Count: 0
  • ScopedCounterComponent Instance 1 Display: Count: 0
  • ScopedCounterComponent Instance 2 Display: Count: 0

Explanation: All services are initialized with a count of 0. The AppComponent uses a root-provided service, while each ScopedCounterComponent uses its own unique, scoped instance.

Example 2: Interaction with AppComponent

  • User clicks the "Increment Root Count" button in AppComponent.
  • AppComponent Display: Count: 1
  • ScopedCounterComponent Instance 1 Display: Count: 0 (unaffected)
  • ScopedCounterComponent Instance 2 Display: Count: 0 (unaffected)

Explanation: Only the root-scoped CounterService instance is affected by the AppComponent's actions.

Example 3: Interaction with ScopedCounterComponent

  • User clicks the "Increment My Count" button in ScopedCounterComponent Instance 1.
  • AppComponent Display: Count: 1 (unaffected)
  • ScopedCounterComponent Instance 1 Display: Count: 1
  • ScopedCounterComponent Instance 2 Display: Count: 0 (unaffected)

Explanation: Clicking the button in ScopedCounterComponent Instance 1 only affects its specific, scoped CounterService instance.

Constraints

  • Angular version: v14+
  • Language: TypeScript
  • The CounterService should be provided in the providers array of the ScopedCounterComponent decorator.
  • The AppComponent should not have the CounterService in its providers array, implying it should be provided at the root (AppModule or bootstrapApplication).

Notes

  • Remember to make CounterService a providedIn: 'root' service initially, and then override this behavior for ScopedCounterComponent by providing it directly in its decorator.
  • Pay close attention to where the CounterService is injected in AppComponent versus ScopedCounterComponent.
  • You'll need to set up a basic Angular project with these components. The exact structure of the project (e.g., using modules or standalone components) is flexible as long as the core requirement of scoped service provision is met.
  • Success is measured by the independent behavior of the counters as described in the examples.
Loading editor...
typescript