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:
- Module Structure: Create a new Angular module file (
core.module.ts). - 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 likelog(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 likegetTitle(): string.
- Singleton Services: Ensure that both
LoggerServiceandConfigServiceare provided as singletons within theCoreModuleand are therefore available throughout the application without being re-instantiated. - Exporting Services: The
CoreModulemust exportLoggerServiceandConfigServiceso that other modules can import and use them. - No Component Declarations: The
CoreModuleshould not declare any components. It is purely for providing services. - Importing into AppModule: The
CoreModulemust be imported into theAppModuleof 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.
LoggerServiceshould log toconsole.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 explicitprovidersarray inCoreModuleif you are only providing services. However, for explicit module-based provisioning demonstration, you might choose to add them to theprovidersarray ofCoreModuleand export the services. For this challenge, focus on understanding howCoreModulecontributes to making services available. - The
CoreModuleshould ideally be imported only once in yourAppModule. Feature modules should then be able to import the services provided byCoreModule(by importingCoreModuleitself, or byCoreModuleexporting the services and feature modules importing those exports). The most common pattern is forCoreModuleto export its services, and for feature modules to importCoreModuleto gain access to those exports. - Think about the
importsandexportsarrays within your@NgModuledecorator.