Services and Dependency Injection
What Are Services?
A service is a class that provides shared logic, data access, or cross-cutting concerns to multiple components. Services handle things like fetching data from an API, caching, logging, or business logic — keeping components lean and focused on the view.
Dependency Injection (DI) is Angular's mechanism for providing services to the classes that need them. Instead of instantiating services manually with new, you declare them as constructor parameters and Angular's injector creates and delivers them automatically.
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class UserService {
private users = [
{ id: 1, name: 'Alice', role: 'admin' },
{ id: 2, name: 'Bob', role: 'viewer' }
];
getAll() {
return [...this.users];
}
getById(id: number) {
return this.users.find(u => u.id === id);
}
add(name: string, role: string) {
const newUser = { id: Date.now(), name, role };
this.users.push(newUser);
return newUser;
}
}providedIn: 'root' registers the service as a singleton in the root injector. This means every component that injects UserService gets the same instance, which is exactly what you want for shared state.
Injecting a Service into a Component
import { Component, OnInit, inject } from '@angular/core';
import { UserService } from '../services/user.service';
@Component({
selector: 'app-user-list',
standalone: true,
template: `
<ul>
@for (user of users; track user.id) {
<li>{{ user.name }} ({{ user.role }})</li>
}
</ul>
`
})
export class UserListComponent implements OnInit {
// Modern approach: function-based injection
private userService = inject(UserService);
users: { id: number; name: string; role: string }[] = [];
ngOnInit() {
this.users = this.userService.getAll();
}
}Angular 14+ introduced the inject() function as an alternative to constructor injection. It is cleaner in standalone components and is preferred in modern Angular code. Both styles are fully supported.