Angular
Tutorial Angular: Servicios en Angular
Angular servicios: creación y uso. Aprende a crear y usar servicios en Angular con ejemplos prácticos y detallados.
Aprende Angular GRATIS y certifícateLos servicios en Angular son clases que encapsulan la lógica y los datos específicos de una aplicación. Se utilizan para compartir información y funcionalidades entre componentes a través de la inyección de dependencias.
Creación de un servicio
Los servicios se crean una vez y se pueden inyectar en varios componentes, lo que promueve la reutilización del código y la separación de responsabilidades.
Para crear un servicio en Angular, primero se debe generar una clase TypeScript decorada con el decorador @Injectable()
. Esto le permite a Angular saber que el servicio puede ser inyectado en otros componentes o servicios.
Comandos para crear un servicio
Usando Angular CLI:
ng generate service nombre-del-servicio
o la versión abreviada:
ng g s nombre-del-servicio
Para crear un servicio dentro de una carpeta específica:
ng generate service ruta/nombre-del-servicio
Estos comandos generarán automáticamente un archivo de servicio con la estructura básica y el decorador @Injectable()
.
A continuación se presenta un ejemplo de código que define un servicio llamado DataService
:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class DataService {
private data: string[] = [];
addData(item: string): void {
this.data.push(item);
}
getData(): string[] {
return this.data;
}
}
En este ejemplo, el servicio DataService
encapsula la lógica y el estado para agregar y recuperar datos.
La opción providedIn: 'root'
dentro del decorador @Injectable()
garantiza que Angular cree una única instancia del servicio a nivel de aplicación, lo que permite compartir los mismos datos y métodos entre múltiples componentes que lo utilicen.
En Angular, incluyendo las versiones más recientes, es técnicamente posible crear servicios sin el decorador @Injectable()
en algunos casos. Sin embargo, se recomienda siempre usar @Injectable()
como buena práctica, incluso si el servicio no tiene dependencias inicialmente. Esto mantiene la consistencia del código y facilita futuras modificaciones.
Inyección de dependencias
Una vez que el servicio ha sido definido, puede ser inyectado en componentes que lo requieran.
La inyección de dependencias es una práctica en la que se proporcionan instancias de clases necesarias en lugar de crearlas directamente.
Angular se encarga de crear una sola instancia del servicio y la comparte entre todos los componentes que lo soliciten.
A continuación, se muestra cómo se realiza la inyección del servicio DataService
en un componente:
import { Component } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-data',
template: `
<button (click)="addData()">Agregar Dato</button>
<ul>
<li *ngFor="let item of dataService.getData()">{{ item }}</li>
</ul>
`
})
export class DataComponent {
constructor(private dataService: DataService) {}
addData(): void {
this.dataService.addData('Nuevo dato');
}
}
En este ejemplo, la inyección de dependencias se logra a través del constructor del componente. Al interactuar con el servicio DataService
, el componente administra los datos sin involucrarse en la implementación subyacente.
Inyección de dependencias en Angular 17+
En Angular 17+, la inyección de dependencias en componentes ha sido simplificada. Ahora puedes usar la sintaxis de inyección en el constructor de forma más concisa con inject()
:
import { Component, inject } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-data',
standalone: true,
imports: [NgFor],
template: `
<button (click)="addData()">Agregar Dato</button>
<ul>
<li *ngFor="let item of dataService.getData()">{{ item }}</li>
</ul>
`
})
export class DataComponent {
dataService = inject(DataService);
addData(): void {
this.dataService.addData('Nuevo dato');
}
}
Nota que este componente está definido como standalone
, una característica introducida en versiones recientes de Angular que permite crear componentes sin necesidad de declararlos en un módulo.
Ámbito y ciclo de vida de un servicio
El ámbito y el ciclo de vida de un servicio en Angular están determinados por la propiedad providedIn
en el objeto de metadatos del decorador @Injectable()
.
Esta propiedad indica dónde se proporciona el servicio y cómo se administran las instancias del servicio.
providedIn: 'root'
: Esta opción indica que el servicio se proporciona a nivel de la aplicación y se crea una única instancia (singleton) para toda la aplicación. Es la opción predeterminada y es recomendable para la mayoría de los servicios que requieren un estado compartido a nivel de la aplicación.
providedIn: 'any'
: Una nueva opción que crea una instancia separada del servicio para cada módulo lazy-loaded que lo inyecte.
providedIn: SomeModule
: Esta opción indica que el servicio se proporciona en el nivel del módulo especificado (en este ejemplo, SomeModule
). Angular crea una instancia única del servicio para cada módulo que lo requiera. Al utilizar esta opción, se debe importar y agregar el servicio a la lista de providers
del módulo correspondiente.
Ejemplo de un servicio proporcionado a nivel de módulo
Supongamos que hay un servicio llamado AuthService
que maneja la autenticación de usuarios en una aplicación.
Se busca que este servicio esté disponible solo para un módulo específico llamado AuthModule
, y no para toda la aplicación.
Aquí está el ejemplo:
// auth.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: AuthModule // Se especifica la provisión dentro del módulo AuthModule
})
export class AuthService {
}
// auth.module.ts
import { NgModule } from '@angular/core';
import { AuthService } from './auth.service';
@NgModule({
providers: [AuthService], // Se agrega el servicio al arreglo de proveedores del módulo
// Otros metadatos y configuraciones del módulo
})
export class AuthModule { }
Para lograr que el servicio esté disponible para ser inyectado en otros componentes, se debe proporcionar un proveedor para el servicio. Esto se hace en el metadato providers
del módulo raíz o de un módulo específico, como en este ejemplo.
Proporcionar el servicio en un componente
Se puede proporcionar un servicio a nivel de componente agregándolo a la lista de providers en el decorador @Component
.
Esto creará una nueva instancia del servicio para cada instancia del componente.
import { Component } from '@angular/core';
import { UserService } from './user.service';
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
providers: [UserService]
})
export class UsersComponent {
}
Para componentes standalone:
@Component({
standalone: true,
providers: [UserService]
})
export class UsersComponent {
constructor(private userService: UserService) {}
}
Observables en servicios
Los Observables son una característica proveniente de la biblioteca RxJS (Reactive Extensions for JavaScript). Un Observable representa una fuente de valores, o eventos, que uno puede "observar".
Los servicios en Angular a menudo se utilizan para recuperar, procesar y enviar datos. Cuando estos procesos son asincrónicos, como la recuperación de datos de una API, los Observables son una herramienta valiosa.
A continuación, se muestra un ejemplo sencillo de cómo se puede crear un servicio en Angular que utiliza Observables para recuperar datos de una API:
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataService {
private http = inject(HttpClient);
private apiUrl = 'https://api.ejemplo.com/datos';
obtenerDatos(): Observable<any> {
return this.http.get(this.apiUrl);
}
}
En este ejemplo, el servicio DataService
utiliza el módulo HttpClient
para hacer una solicitud GET a una API.
La función obtenerDatos()
devuelve un Observable que emitirá los datos cuando estén disponibles.
Suscripción a Observables
Para "escuchar" o "observar" los valores que emite un Observable, es necesario "suscribirse" a él.
La suscripción se realiza utilizando el método subscribe()
del Observable.
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-ejemplo',
template: `
<div *ngIf="datos">
{{ datos }}
</div>
`
})
export class EjemploComponent implements OnInit {
datos: any;
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.obtenerDatos().subscribe({
next: (data) => this.datos = data,
error: (error) => console.error('Ocurrió un error:', error)
});
}
}
En el componente EjemploComponent
, se suscribe al Observable devuelto por obtenerDatos()
. Cuando los datos estén disponibles, se asignarán al miembro datos
del componente.
En las últimas versiones de Angular se ha introducido una nueva sintaxis para trabajar con Observables en las plantillas, eliminando la necesidad de suscribirse manualmente en muchos casos
import { Component } from '@angular/core';
import { AsyncPipe } from '@angular/common';
import { DataService } from './data.service';
@Component({
selector: 'app-ejemplo',
standalone: true,
imports: [AsyncPipe],
template: `
<div *ngIf="datos$ | async as datos">
{{ datos }}
</div>
`
})
export class EjemploComponent {
datos$ = this.dataService.obtenerDatos();
constructor(private dataService: DataService) {}
}
En este ejemplo, se usa el pipe async
en la plantilla para manejar la suscripción al Observable, lo que simplifica el código y evita la necesidad de gestionar manualmente la suscripción y la limpieza.
Ejercicios de esta lección Servicios en Angular
Evalúa tus conocimientos de esta lección Servicios en Angular con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Signals en Angular
Guards funcionales
Decodificar JWT en Angular
Servicio con HttpClient
Ciclo de vida de componentes en Angular
Gestión de productos de Fake Store API
Data binding en Angular
Routes sin módulos en Angular
Router en Angular
Instalación de Angular
Route Guards basados en interfaces
La directiva @if en Angular
Formularios reactivos en Angular
Servicios en Angular
Interceptor funcional
Servicio con Array
La directiva @for en Angular
Interceptores HTTP
Componentes standalone true
Formularios con ngModel en Angular
Routes en Angular
Comunicación entre componentes Angular
Parámetros en rutas con ActivatedRoute
CRUD de Restaurantes y Platos
Tablas en Angular Material
Formulario de registro de usuarios
Instalación y uso de NgBoostrap
Desarrollo de componentes Angular
JWT en Angular
Formularios reactivos en Angular
Formularios en Angular Material
Layout con Angular Material
Effects en Angular
Data binding
HttpClient en servicios de Angular
Desarrollo de módulos Angular
Comandos Angular CLI
Subir archivo en formularios
La directiva routerLink en Angular
Todas las lecciones de Angular
Accede a todas las lecciones de Angular y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Instalación Angular
Introducción Y Entorno
Comandos Angular Cli
Introducción Y Entorno
Desarrollo De Componentes Angular
Componentes
Data Binding En Angular
Componentes
Ciclo De Vida De Componentes En Angular
Componentes
Comunicación Entre Componentes Angular
Componentes
La Directiva @If En Angular
Componentes
La Directiva @For En Angular
Componentes
Componentes Standalone
Componentes
Desarrollo De Módulos Angular
Módulos
Routes En Angular
Enrutado Y Navegación
Router En Angular
Enrutado Y Navegación
La Directiva Routerlink En Angular
Enrutado Y Navegación
Parámetros En Rutas Con Activatedroute
Enrutado Y Navegación
Routes Sin Módulos En Angular
Enrutado Y Navegación
Servicios En Angular
Servicios E Inyección De Dependencias
Httpclient En Servicios De Angular
Servicios E Inyección De Dependencias
Formularios Con Ngmodel En Angular
Formularios
Formularios Reactivos En Angular
Formularios
Subir Archivo En Formularios
Formularios
Layout Con Angular Material
Integración Con Angular Material
Tablas En Angular Material
Integración Con Angular Material
Formularios En Angular Material
Integración Con Angular Material
Instalación Y Uso De Ngboostrap
Integración Con Bootstrap Css
Signals En Angular
Signals Y Reactividad
Effects En Angular
Signals Y Reactividad
Route Guards Basados En Interfaces
Autenticación Y Autorización
Guards Funcionales
Autenticación Y Autorización
Interceptores Http Basados En Interfaz
Autenticación Y Autorización
Interceptores Http Funcionales
Autenticación Y Autorización
Seguridad Jwt En Angular
Autenticación Y Autorización
Decodificar Tokens Jwt En Angular
Autenticación Y Autorización
Certificados de superación de Angular
Supera todos los ejercicios de programación del curso de Angular y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.
En esta lección
Objetivos de aprendizaje de esta lección
- Aprender a crear servicios en Angular.
- Comprender el concepto de inyección de dependencias.
- Entender el ámbito y el ciclo de vida de un servicio.
- Conocer la configuración de proveedores de servicios.
- Familiarizarse con Observables en servicios.