Angular 20

Angular Services & Dependency Injection – Complete Guide with Examples

Chapter 7: Services and Dependency Injection in Angular

Angular services allow you to organize and share business logic, API communication, and reusable data across components. Dependency Injection (DI) is the design pattern Angular uses to deliver these services efficiently and modularly.

What is a Service in Angular?

A service is a reusable class that encapsulates logic not directly related to views or UI. Common use cases include HTTP calls, data persistence, and utilities like logging or authentication.

Creating a Service

Using Angular CLI


ng generate service user
  

This command creates user.service.ts with a boilerplate structure and the @Injectable() decorator.

Using the @Injectable() Decorator

The @Injectable() decorator marks a class as available to be injected as a dependency. Here’s an example:


import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class UserService {
  getUsers() {
    return ['John', 'Jane', 'Doe'];
  }
}
  

The providedIn: 'root' syntax automatically registers this service in the application’s root injector, making it app-wide.

Injecting Services into Components

To use a service, inject it into a component’s constructor:


import { Component } from '@angular/core';
import { UserService } from './user.service';

@Component({
  selector: 'app-user-list',
  template: `
    <ul>
      <li *ngFor="let user of users">{{ user }}</li>
    </ul>
  `
})
export class UserListComponent {
  users: string[] = [];

  constructor(private userService: UserService) {
    this.users = this.userService.getUsers();
  }
}
  

Service Scope: App-wide vs Local

1. App-wide (Global) Scope

When you provide a service in the root injector (with providedIn: 'root'), it is available throughout the app, and a single instance is shared:


@Injectable({
  providedIn: 'root'
})
export class LoggerService { ... }
  

2. Local Scope (Component-level)

You can provide a service only to a specific component and its children by declaring it in the component’s providers array:


@Component({
  selector: 'app-local',
  templateUrl: './local.component.html',
  providers: [LocalService]
})
export class LocalComponent { ... }
  

This creates a new instance of the service for that component only, ideal for isolating state or behavior.

Best Practices

  • Use services for business logic and data access, not UI code.
  • Prefer providedIn: 'root' for stateless services to avoid manual registration.
  • Inject services via constructor injection to leverage Angular’s DI system.
  • Avoid creating multiple instances of the same service unless necessary (e.g., component-specific state).

Conclusion

Services and Dependency Injection are core to scalable Angular applications. They separate logic from UI, reduce redundancy, and promote modular architecture. Whether used globally or locally, services empower your app to stay clean and maintainable.

Next Steps

In Chapter 8, we’ll dive into HTTP communication in Angular, including how to use the HttpClient module to make API requests and handle responses with Observables.

Leave a Reply

Your email address will not be published. Required fields are marked *