This tutorial aims to guide you through the concept of Dependency Injection (DI) in Angular. Angular's DI is a design pattern in which a class receives its dependencies from external sources rather than creating them itself. This makes your code more reusable, modular, and easier to test.
By the end of this tutorial, you will:
Prerequisites:
Familiarity with Angular and Typescript will be beneficial.
In Angular, DI is implemented by the @Injectable()
decorator. When a class is marked with this decorator, Angular knows that it could be used as a provider, i.e., a source of dependencies for other classes.
When a class needs a service, instead of directly creating an instance of the service, it will ask the Angular injector. If the injector can find the service, it will inject it; otherwise, it will throw an error.
@Injectable()
decorator for any service that you want to be injectable.{ providedIn: 'root' }
for services that should be singleton (only one instance for the entire app).// app.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root', // This service is available throughout the app
})
export class AppService {
getMessage(): string {
return 'Hello from AppService!';
}
}
In this code snippet, we define a service AppService
with a method getMessage()
.
// app.component.ts
import { Component } from '@angular/core';
import { AppService } from './app.service';
@Component({
selector: 'app-root',
template: `<h1>{{ message }}</h1>`,
})
export class AppComponent {
message: string;
constructor(private appService: AppService) {
this.message = this.appService.getMessage();
}
}
In AppComponent
, we inject AppService
in the constructor and use it to get a message.
In this tutorial, we have learned about Dependency Injection (DI) in Angular, why it's beneficial, and how to implement it to make our code more modular, reusable, and testable. We've seen how the @Injectable()
decorator is used to make a service injectable and how to inject services into components using the constructor.
For further reading, check out the official Angular documentation on Dependency Injection.
LoggerService
with a method log(message: string)
. Inject it into AppComponent
and call the log
method.LoggerService
to include a logError(message: string)
method. Update AppComponent
to use this new method.Solutions:
// logger.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class LoggerService {
log(message: string) {
console.log(message);
}
logError(message: string) {
console.error(message);
}
}
// app.component.ts
import { Component } from '@angular/core';
import { LoggerService } from './logger.service';
@Component({
selector: 'app-root',
template: `<h1>Hello, world!</h1>`,
})
export class AppComponent {
constructor(private logger: LoggerService) {
this.logger.log('Hello from AppComponent');
this.logger.logError('This is an error message');
}
}
Keep practicing and exploring other Angular concepts!