← Back to Chapters

Angular – Creating & Using Services

⚙️ Angular – Creating & Using Services

Angular Services · Reusable Logic · Dependency Injection

? Quick Overview

In Angular, services are used to encapsulate reusable logic that can be shared across components. They commonly handle:

  • Data fetching (HTTP calls, APIs)
  • Business logic and calculations
  • State management and shared data
  • Cross-cutting tasks like logging or authentication helpers

?️ Key Concepts

  • @Injectable decorator marks a class as available for dependency injection.
  • providedIn: 'root' makes the service a singleton at application level.
  • Dependency Injection (DI) lets Angular create and supply service instances to components.
  • Services help achieve separation of concerns and promote code reusability.

? Syntax & Theory

A typical Angular service is a TypeScript class decorated with @Injectable(). It contains methods that can be called from any component where the service is injected.

  1. Create a service class (e.g., data.service.ts).
  2. Decorate it with @Injectable({ providedIn: 'root' }).
  3. Inject it into a component via the constructor.
  4. Call its methods to get or update shared data.

? Creating a Service

This service stores a list of JavaScript frameworks and exposes methods to read and update the list.

? View Code Example – Service (data.service.ts)
// data.service.ts - reusable data service for frameworks
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private data: string[] = ['Angular', 'React', 'Vue'];

  constructor() { }

  getData(): string[] {
    return this.data;
  }

  addData(item: string) {
    this.data.push(item);
  }
}

? Using a Service in a Component

The component injects DataService and displays the frameworks returned by the service.

? View Code Example – Component (app.component.ts)
// app.component.ts - consuming DataService in a component
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-root',
  template: `
    <h2>Frameworks</h2>
    <ul>
      <li *ngFor="let item of frameworks">{{ item }}</li>
    </ul>
  `
})
export class AppComponent implements OnInit {
  frameworks: string[] = [];

  constructor(private dataService: DataService) { }

  ngOnInit() {
    this.frameworks = this.dataService.getData();
  }
}

? Live Output / Explanation

If the above component is rendered, the browser will display:

Frameworks
- Angular
- React
- Vue
  • @Injectable({ providedIn: 'root' }) registers DataService as a singleton service at the root level.
  • The component receives the service instance via the constructor: constructor(private dataService: DataService).
  • ngOnInit() calls getData() to fetch the list of frameworks and assigns it to the frameworks array.
  • The template uses *ngFor to loop through frameworks and render each item in a list.

✅ Tips & Best Practices

  • Use services for shared state or data across multiple components.
  • Keep each service focused on a single responsibility (e.g., user service, cart service, auth service).
  • Avoid putting component-specific UI logic in services; keep them for business or shared logic.
  • Leverage Angular’s dependency injection to avoid manual object creation and to improve testability.

? Try It Yourself

  • Create a CartService to manage a shopping cart in an e-commerce app.
  • Add methods like addItem(), removeItem(), and getItems().
  • Inject the service into multiple components (e.g., product list, cart summary, checkout page).
  • Display the shared cart data in each component and verify that updates in one place reflect everywhere.