Angular Tutorial menu

Angular Services and Dependency Injection

A service is a class that holds logic or data that several components need, such as a cart or a list of courses.

Why Services?

Components should focus on showing the screen. Work like these belongs in services:

  • Loading and saving data from a server
  • Sharing data between components, such as a shopping cart
  • Common helpers, like formatting or logging

Creating a Service

Example

bash
ng generate service cart

This creates cart.ts (named cart.service.ts in versions before Angular 20). Write the service:

Example

typescript
import { Injectable, signal, computed } from "@angular/core";

export interface CartItem {
  name: string;
  price: number;
}

@Injectable({ providedIn: "root" })
export class CartService {
  private items = signal<CartItem[]>([]);

  readonly list = this.items.asReadonly();
  readonly total = computed(() => this.items().reduce((sum, i) => sum + i.price, 0));

  add(item: CartItem) {
    this.items.update((list) => [...list, item]);
  }

  clear() {
    this.items.set([]);
  }
}

@Injectable({ providedIn: "root" }) means Angular creates one shared copy of the service for the whole app.

Using a Service with inject()

Components get services with the inject() function. This is called dependency injection: you ask for what you need, and Angular gives it to you.

Example

typescript
import { Component, inject } from "@angular/core";
import { CartService } from "./cart";

@Component({
  selector: "app-product",
  template: `
    <h3>Cricket Bat</h3>
    <p>Rs 4,500</p>
    <button (click)="cart.add({ name: 'Cricket Bat', price: 4500 })">Add to cart</button>
  `,
})
export class Product {
  cart = inject(CartService);
}

Another component can read the same cart:

Example

typescript
@Component({
  selector: "app-cart-summary",
  template: `<p>{{ cart.list().length }} items, total Rs {{ cart.total() }}</p>`,
})
export class CartSummary {
  cart = inject(CartService);
}
Output
(after adding the bat twice)
2 items, total Rs 9000

Both components use the same CartService, so they always agree.

You may see services injected through the constructor: constructor(private cart: CartService) {}. It still works. inject() is shorter and the modern style.

Loading Data with HttpClient

Angular's HttpClient talks to servers. First, provide it in app.config.ts:

Example

typescript
import { ApplicationConfig } from "@angular/core";
import { provideHttpClient } from "@angular/common/http";

export const appConfig: ApplicationConfig = {
  providers: [provideHttpClient()],
};

Then use it in a service:

Example

typescript
import { Injectable, inject } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs";

export interface User {
  id: number;
  name: string;
}

@Injectable({ providedIn: "root" })
export class UserService {
  private http = inject(HttpClient);

  getUsers(): Observable<User[]> {
    return this.http.get<User[]>("https://jsonplaceholder.typicode.com/users");
  }
}

And show the result in a component. toSignal turns the HTTP result into a signal:

Example

typescript
import { Component, inject } from "@angular/core";
import { toSignal } from "@angular/core/rxjs-interop";
import { UserService } from "./user";

@Component({
  selector: "app-users",
  template: `
    @for (u of users(); track u.id) {
      <p>{{ u.name }}</p>
    } @empty {
      <p>Loading...</p>
    }
  `,
})
export class Users {
  users = toSignal(inject(UserService).getUsers(), { initialValue: [] });
}

HttpClient returns an Observable from the RxJS library. You will learn more about RxJS as you build larger apps.

Summary

IdeaCode
Make a class injectable@Injectable({ providedIn: "root" })
Get a serviceinject(CartService)
Enable HTTPprovideHttpClient() in app.config.ts
GET requestthis.http.get<T>(url)

Exercise

Exercise

What does providedIn: "root" mean for a service?

Learn Angular with a teacher

Join the Full Stack Development course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp