Hone logo
Hone
Problems

Angular Core Module Implementation

This challenge focuses on building a fundamental "Core Module" in an Angular application. A well-structured Core Module is crucial for organizing shared services, utilities, and components that are used across multiple feature modules. Successfully implementing this will demonstrate your understanding of Angular's modular architecture and best practices.

Problem Description

Your task is to create an Angular module named CoreModule. This module should contain and export essential services that will be available application-wide. It should also include any global configurations or constants needed by these services.

Key Requirements:

  1. Module Structure: Create a new Angular module file (core.module.ts).
  2. Service Provisioning: Implement at least two distinct services:
    • LoggerService: A simple service to log messages (e.g., to the console). It should have a method like log(message: string): void.
    • ConfigService: A service that holds some application-level configuration. For this challenge, it can simply store a title property. It should have a method like getTitle(): string.
  3. Singleton Services: Ensure that both LoggerService and ConfigService are provided as singletons within the CoreModule and are therefore available throughout the application without being re-instantiated.
  4. Exporting Services: The CoreModule must export LoggerService and ConfigService so that other modules can import and use them.
  5. No Component Declarations: The CoreModule should not declare any components. It is purely for providing services.
  6. Importing into AppModule: The CoreModule must be imported into the AppModule of your Angular application.

Expected Behavior:

When LoggerService and ConfigService are injected into components or other services in different feature modules (or even in AppComponent), they should be the same instances throughout the application. Calling LoggerService.log() should output messages to the browser console. Calling ConfigService.getTitle() should return the configured title.

Edge Cases:

  • Ensure services are correctly injected and accessible even if they are not directly used in AppComponent.
  • Verify that the services are indeed singletons.

Examples

Example 1: Basic Service Usage

// app.component.ts (or any other component/service)
import { Component, OnInit } from '@angular/core';
import { LoggerService } from '../core/services/logger.service'; // Assuming path
import { ConfigService } from '../core/services/config.service'; // Assuming path

@Component({
  selector: 'app-root',
  template: `<h1>{{ appTitle }}</h1>`,
})
export class AppComponent implements OnInit {
  appTitle: string = '';

  constructor(
    private logger: LoggerService,
    private config: ConfigService
  ) {}

  ngOnInit(): void {
    this.logger.log('AppComponent initialized.');
    this.appTitle = this.config.getTitle();
    this.logger.log(`Application Title: ${this.appTitle}`);
  }
}

Expected Output (in browser console):

AppComponent initialized.
Application Title: My Awesome App

Expected Template Output:

<h1>My Awesome App</h1>

Explanation:

The AppComponent successfully injects both LoggerService and ConfigService. ngOnInit logs a message and then retrieves the application title from ConfigService to display in the template and log again.

Example 2: Singleton Verification (Conceptual)

Imagine another component, FeatureComponent, also injected with LoggerService:

// feature.component.ts (in a different module, imported into AppModule)
import { Component, OnInit } from '@angular/core';
import { LoggerService } from '../core/services/logger.service'; // Assuming path

@Component({
  selector: 'app-feature',
  template: `<p>Check the console!</p>`,
})
export class FeatureComponent implements OnInit {
  constructor(private logger: LoggerService) {}

  ngOnInit(): void {
    this.logger.log('FeatureComponent is also logging!');
  }
}

Expected Output (in browser console, alongside Example 1):

AppComponent initialized.
Application Title: My Awesome App
FeatureComponent is also logging!

Explanation:

The fact that FeatureComponent can inject and use LoggerService (and it's the same instance as used by AppComponent) confirms the singleton nature and correct provisioning of the service through CoreModule.

Constraints

  • Angular CLI project setup is assumed.
  • Solution must be written in TypeScript.
  • LoggerService should log to console.log().
  • ConfigService's title should be hardcoded within the service implementation for this challenge (e.g., "My Awesome App").

Notes

  • Consider using the providedIn: 'root' option when decorating your services with @Injectable(). This is the modern and recommended way to make services available as singletons throughout the application, and it often eliminates the need for explicit providers array in CoreModule if you are only providing services. However, for explicit module-based provisioning demonstration, you might choose to add them to the providers array of CoreModule and export the services. For this challenge, focus on understanding how CoreModule contributes to making services available.
  • The CoreModule should ideally be imported only once in your AppModule. Feature modules should then be able to import the services provided by CoreModule (by importing CoreModule itself, or by CoreModule exporting the services and feature modules importing those exports). The most common pattern is for CoreModule to export its services, and for feature modules to import CoreModule to gain access to those exports.
  • Think about the imports and exports arrays within your @NgModule decorator.
Loading editor...
typescript