Hone logo
Hone
Problems

Angular Hierarchical Injection Challenge

Angular's dependency injection (DI) system is powerful and flexible, allowing for the creation of loosely coupled and testable applications. A key feature of this system is hierarchical injection, where services can be provided at different levels of the component tree. This challenge will test your understanding and ability to implement services at various scopes within an Angular application.

Problem Description

You are tasked with building a simple Angular application that demonstrates hierarchical injection. Your application will consist of a root component, a parent component, and a child component. You need to create a service that can be injected and used differently at each level.

Key Requirements:

  1. Root-Level Service: Create a service (RootDataService) that is provided at the root of the application. All components should be able to access an instance of this service.
  2. Parent-Level Service: Create another service (ParentDataService) that is provided at the AppComponent's parent. This service should have a distinct instance from any ParentDataService potentially provided at lower levels.
  3. Child-Level Service: Create a third service (ChildDataService) that is provided specifically at the ChildComponent level. This instance should be unique to the ChildComponent and its descendants.
  4. Component Implementation:
    • AppComponent: Inject RootDataService and ParentDataService. Display a unique identifier for each service instance.
    • ParentComponent: Inject RootDataService and ParentDataService. Display a unique identifier for each service instance.
    • ChildComponent: Inject RootDataService, ParentDataService, and ChildDataService. Display a unique identifier for each service instance.
  5. Displaying Identifiers: Each service should have a property (e.g., id or name) that uniquely identifies its instance. This identifier should be displayed in the component's template to visually confirm which instance is being used.

Expected Behavior:

  • The RootDataService instance should be the same across all three components.
  • The ParentDataService instance injected into AppComponent should be the same as the one injected into ParentComponent.
  • The ParentDataService instance injected into ChildComponent should be a different instance from the one in AppComponent and ParentComponent (because ParentDataService will be provided at the ParentComponent level).
  • The ChildDataService instance should be unique to ChildComponent.

Edge Cases:

  • Ensure that attempting to inject ChildDataService into AppComponent or ParentComponent without it being provided at their level results in an injection error, or that it correctly injects the parent's instance if provided higher up. (For this challenge, focus on the successful injection paths described above).

Examples

Example 1: Service Instance Identifiers

Let's assume each service has a name property for identification.

RootDataService instance: RootService-123 ParentDataService instance in AppComponent/ParentComponent: ParentService-456 ParentDataService instance in ChildComponent: ParentService-789 ChildDataService instance in ChildComponent: ChildService-ABC

Example 2: Component Templates (Conceptual)

AppComponent Template:

<p>Root Data Service: {{ rootService.name }}</p>
<p>Parent Data Service: {{ parentService.name }}</p>
<app-parent></app-parent>

ParentComponent Template:

<p>Parent Component - Root Data Service: {{ rootService.name }}</p>
<p>Parent Component - Parent Data Service: {{ parentService.name }}</p>
<app-child></app-child>

ChildComponent Template:

<p>Child Component - Root Data Service: {{ rootService.name }}</p>
<p>Child Component - Parent Data Service: {{ parentService.name }}</p>
<p>Child Component - Child Data Service: {{ childService.name }}</p>

Explanation:

The output in the browser will show the unique identifiers for each service instance. By comparing these identifiers across components, you can verify that the correct service instances are being injected based on their provider scopes.

Constraints

  • Your solution must be implemented using TypeScript.
  • You will need to create at least three distinct service classes.
  • Services must be provided using @Injectable() decorators and appropriately configured in the providers array of modules or components.
  • The application structure should involve at least three components: AppComponent, ParentComponent, and ChildComponent, with ChildComponent nested within ParentComponent, which is nested within AppComponent.

Notes

  • Consider using a simple counter or a UUID generator within your services to create unique instance identifiers.
  • Remember to register your services using providedIn: 'root' for the root-level service, and to configure the providers array in the @Component decorator for the parent and child level services.
  • Pay close attention to the providedIn property and the providers array in component decorators when defining where services are available.
  • The goal is to demonstrate the cascading nature of dependency injection in Angular.
Loading editor...
typescript