ANGULAR: Angular Services

Angular services are singleton classes that centralize business logic, data fetching, and shared state away from components. They keep components lean and focused on the UI while making logic reusable across the entire application.

Services in Angular are the packages that hold the logic for a component. While components are responsible for the user interface, services handle everything else — data fetching, business rules, state management, and communication with APIs.

Separating logic into services keeps components clean and makes the application easier to test and maintain.


Why Use Services

Without services, every component would need to duplicate its own data-fetching and logic code. Services solve this by providing a single, shared location for logic that multiple components can use.

md
Without Services                 With Services
----------------                 -------------

Component A                      Component A
  - fetch data    (duplicate)       - uses service
  - process data  (duplicate)       |
                                    v
Component B                      +----------+
  - fetch data    (duplicate)    | Service  | <-- Single source
  - process data  (duplicate)    +----------+
                                    ^
                                    |
                                 Component B
                                   - uses service


Generating a Service

The Angular CLI creates a service with the correct structure:

bash
ng generate service <service-name>
# or the shorthand:
ng g s <service-name>

This creates a file with the @Injectable decorator already applied:

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

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

  constructor() { }
}


Understanding `@Injectable`

The @Injectable decorator marks a class as available for Angular's dependency injection system. The providedIn: 'root' configuration registers the service at the application root level.

Services in Angular are **singletons**. There is only one instance of the service shared across the entire application.

This means all components that inject the same service share the same instance — making services ideal for shared state like a shopping cart, user session, or cached data.


Adding Logic to a Service

A service can hold data, methods, and state:

typescript
import { Injectable } from '@angular/core';
import { IProduct } from './product.model';

@Injectable({
  providedIn: 'root'
})
export class CartService {
  private cartItems: IProduct[] = [];

  addToCart(product: IProduct): void {
    this.cartItems.push(product);
  }

  removeFromCart(productId: number): void {
    this.cartItems = this.cartItems.filter(item => item.id !== productId);
  }

  getCartItems(): IProduct[] {
    return this.cartItems;
  }

  getCartTotal(): number {
    return this.cartItems.reduce((total, item) => total + item.price, 0);
  }
}


Injecting a Service into a Component

To use a service in a component, declare it in the constructor. Angular's dependency injection system automatically provides the singleton instance:

typescript
import { Component, OnInit } from '@angular/core';
import { CartService } from './cart.service';
import { IProduct } from './product.model';

export class CartComponent implements OnInit {
  cartItems: IProduct[] = [];
  cartTotal: number = 0;

  constructor(private cartService: CartService) {}

  ngOnInit(): void {
    this.cartItems = this.cartService.getCartItems();
    this.cartTotal = this.cartService.getCartTotal();
  }

  remove(productId: number): void {
    this.cartService.removeFromCart(productId);
    this.cartItems = this.cartService.getCartItems();
    this.cartTotal = this.cartService.getCartTotal();
  }
}


Service Architecture

A typical Angular feature module uses services as the data and logic layer:

md
+-------------------+
|    Component      |  (UI only — display data, handle user events)
+---------+---------+
          |
          | injects
          v
+-------------------+
|    Service        |  (Logic — business rules, data fetching, state)
+---------+---------+
          |
          | calls
          v
+-------------------+
|   HTTP / API      |  (External data source)
+-------------------+


Summary

Services are the backbone of Angular application architecture. They centralize logic, enable code reuse, and keep components focused purely on the UI.

Key things to remember:

  • Use ng g s to generate a service
  • Services are singletons — one instance shared across the whole app
  • Inject services via the constructor using Angular's dependency injection
  • Keep components thin and move all business logic into services

Well-designed Angular apps have thin components and rich services.