Building the Backbone: Creating Services in Angular

Learn to organize your code, share data, and build scalable applications by mastering Angular Services.

Welcome! Let's build the backbone of our Angular app: a service.

/* Starting our journey into Angular services... */

Creating a Service with the CLI

The fastest way to create a service is with the Angular CLI. Running the command ng generate service my-service (or ng g s my-service) scaffolds a new service class and its test file, saving you time and ensuring your project follows best practices.

The @Injectable() Decorator

The `@Injectable()` decorator marks a class as one that can be managed by Angular's dependency injection system. The `providedIn: 'root'` property automatically provides the service at the application's root level, making it a singleton available to any component.

Dependency Injection in the Constructor

To use a service, you inject it into a component's constructor. You declare it as a private property with its type. Angular's dependency injector sees this, finds the service instance, and passes it to your component automatically. For example: constructor(private dataService: DataService) { }

The Result: Clean, Reusable Logic

By creating and injecting services, you achieve a clean separation of concerns. Your components focus on presentation, while your services handle business logic, data fetching, and state management. This makes your code more modular, reusable, and easier to test.

Practice Zone


Interactive Test 1: Match the Concept

Match the Angular concept to its correct description.

Arrastra en el orden correspondiente.


Arrastra las opciones:

@Injectable({ providedIn: "root" })
constructor(private myService: MyService) {}
ng generate service user-data

Completa el código:

CLI Command______
Decorator______
Injection Point______
Unlock with Premium

Interactive Test 2: Complete the Code

Rellena los huecos en cada casilla.

import {  } from '@angular/core';

@Injectable({
  providedIn: ''
})
export class LoggingService {

  constructor() { }

  log(message: string) {
    console.log(message);
  }
}
Unlock with Premium

Practice Example: Code Editor

Create a service named `ProductService` with a method `getProducts()` that returns an array of product names. Then, create a component that injects this service and displays the products.

Enunciado:

This example shows a self-contained service and a component that immediately uses it in its constructor to fetch and display data.

* Escribe el código a continuación. Los caracteres correctos se mostrarán en verde y los incorrectos en rojo.

// product.service.ts import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class ProductService { getProducts() { return ['Laptop', 'Mouse', 'Keyboard']; } } // product-list.component.ts import { Component } from '@angular/core'; import { ProductService } from './product.service'; @Component({ selector: 'app-product-list', template: '<ul><li *ngFor="let product of products">{{product}}</li></ul>' }) export class ProductListComponent { products: string[] = []; constructor(private productService: ProductService) { this.products = this.productService.getProducts(); } }

Unlock with Premium

Knowledge Check

What does `@Injectable({ providedIn: 'root' })` ensure?


Unlock with Premium

Services in Action

Services are the workhorses of an Angular application, perfect for any logic you need to share across different parts of your app. Here are some common use cases.


1. Centralizing API Calls

Instead of scattering `HttpClient` calls in every component, create a central service (e.g., `ApiService`). This makes it easy to manage base URLs, handle errors, and add headers in one place.

// user-api.service.ts
constructor(private http: HttpClient) {}

getUsers() {
  return this.http.get('/api/users');
}
📡

2. Managing Shared State

Need to know the user's login status or shopping cart contents everywhere? A service is the perfect place to hold that state. Components can inject the service to both read and update the shared data.

// auth.service.ts
private isLoggedIn = new BehaviorSubject(false);
isLoggedIn$ = this.isLoggedIn.asObservable();

login() {
  this.isLoggedIn.next(true);
}
User is Logged In: ✅

3. Abstracting Complex Logic

If you have complex business rules, calculations, or interactions with browser APIs (like `localStorage`), move them into a service. This keeps your components lean and focused only on the UI.

// local-storage.service.ts
saveItem(key: string, value: any) {
  localStorage.setItem(key, JSON.stringify(value));
}
⚙️

Practical Takeaway: Think of services as your application's central nervous system. They manage data, communicate with the outside world, and share information, allowing your components to be simple and focused.

Angular Services Glossary

Service
A class in Angular with a narrow, well-defined purpose. It should do something specific and do it well, such as fetching data, logging, or handling user authentication.
@Injectable()
A decorator that marks a class as available to be provided and injected as a dependency. It's essential for any class you intend to use as a service.
Dependency Injection (DI)
A design pattern in which a class requests dependencies from external sources rather than creating them itself. In Angular, you inject services into component constructors.
Provider
An instruction to the Dependency Injection system on how to obtain a value for a dependency. `providedIn: 'root'` is a common way to provide a service.
Singleton
A class for which only one instance is created. When you provide a service in `'root'`, Angular creates a single, shared instance that is used throughout the entire application.