Skip to content

GitLab

  • Menu
Projects Groups Snippets
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • A angular
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Monitor
    • Monitor
    • Metrics
    • Incidents
  • Packages & Registries
    • Packages & Registries
    • Package Registry
    • Infrastructure Registry
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • imunnic
  • angular
  • Wiki
  • Modulo 4

Modulo 4 · Changes

Page history
born authored Dec 22, 2025 by imunnic's avatar imunnic
Show whitespace changes
Inline Side-by-side
Showing with 287 additions and 0 deletions
+287 -0
  • Modulo-4.md Modulo-4.md +287 -0
  • No files found.
Modulo-4.md 0 → 100644
View page @ 6ca55ed1
# Bloque 4 – Servicios y comunicación con backend (Sesiones 15–19)
Este bloque introduce el uso de servicios en Angular como mecanismo principal para encapsular la lógica de negocio y la comunicación con un backend. Se trabaja con peticiones HTTP reales contra una API de gestión de recursos sanitarios y se profundiza en conceptos clave como Observables, manejo de errores y arquitectura escalable de servicios.
La API base utilizada en todos los ejemplos es:
```
http://localhost:8080/panacea
```
Las rutas concretas de los endpoints se obtienen desde un archivo de configuración centralizado.
---
## Sesión 15 – Servicios en Angular
### Qué es un servicio
Un servicio es una clase cuya responsabilidad principal es encapsular lógica que no pertenece directamente a la vista. Habitualmente se utilizan para acceder a datos remotos, compartir estado entre componentes o implementar reglas de negocio.
El uso de servicios favorece la reutilización de código y mantiene los componentes más simples y enfocados únicamente en la presentación.
### Inyección de dependencias
Angular utiliza un sistema de inyección de dependencias que permite que los servicios se proporcionen automáticamente a los componentes u otros servicios que los necesiten. Esto reduce el acoplamiento y facilita el testeo.
### Servicios singleton
Cuando un servicio se declara con `providedIn: 'root'`, Angular crea una única instancia compartida en toda la aplicación. Este comportamiento es el más habitual para servicios de acceso a datos.
### Creación de servicios
Ejemplo de servicio básico creado con CLI:
```ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class RecursosService {
constructor() {}
}
```
---
## Sesión 16 – HttpClient
### Introducción
`HttpClient` es el servicio proporcionado por Angular para realizar peticiones HTTP. Está basado en Observables y permite tipar las respuestas, interceptar peticiones y manejar errores de forma centralizada.
En aplicaciones modernas con componentes standalone, se configura directamente en el bootstrap de la aplicación.
### Configuración de HttpClient
```ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient } from '@angular/common/http';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, {
providers: [
provideHttpClient()
]
});
```
### Archivo de configuración de endpoints
```json
{
"apiBase": "http://localhost:8080/panacea",
"recursos": "/recursos"
}
```
```ts
import config from '../config.json';
```
### Peticiones GET y POST
```ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import config from '../config.json';
import { Observable } from 'rxjs';
export interface Recurso {
id: number;
nombre: string;
tipo: string;
}
@Injectable({
providedIn: 'root'
})
export class RecursosService {
private baseUrl = config.apiBase + config.recursos;
constructor(private http: HttpClient) {}
obtenerRecursos(): Observable<Recurso[]> {
return this.http.get<Recurso[]>(this.baseUrl);
}
crearRecurso(recurso: Partial<Recurso>): Observable<Recurso> {
return this.http.post<Recurso>(this.baseUrl, recurso);
}
}
```
### Tipado de datos
El tipado de las respuestas permite detectar errores en tiempo de compilación y mejora la experiencia de desarrollo mediante autocompletado y validaciones.
---
## Sesión 17 – Observables y RxJS
### Qué es RxJS y por qué Angular lo usa
RxJS es una librería de programación reactiva basada en flujos de datos asíncronos. Angular la utiliza para gestionar eventos, peticiones HTTP y estados cambiantes de forma declarativa.
### Observable vs Promise
Un Observable puede emitir múltiples valores a lo largo del tiempo y puede cancelarse. Una Promise solo se resuelve una vez y no es cancelable.
### subscribe
```ts
this.recursosService.obtenerRecursos().subscribe({
next: recursos => {
this.recursos = recursos;
},
error: err => {
console.error(err);
}
});
```
### Operadores básicos
```ts
import { map, tap, catchError } from 'rxjs/operators';
import { of } from 'rxjs';
obtenerRecursos() {
return this.http.get<Recurso[]>(this.baseUrl).pipe(
tap(() => console.log('Petición realizada')),
map(recursos => recursos.filter(r => r.tipo === 'SANITARIO')),
catchError(() => of([]))
);
}
```
---
## Sesión 18 – Manejo de errores y estados de carga
### Introducción
Cuando se trabaja con datos remotos es fundamental gestionar correctamente los errores y los estados de carga para ofrecer una buena experiencia de usuario.
### Interceptor de errores HTTP
Un interceptor permite capturar todas las peticiones HTTP y sus respuestas de forma centralizada.
```ts
import { HttpInterceptorFn } from '@angular/common/http';
import { catchError, throwError } from 'rxjs';
export const errorInterceptor: HttpInterceptorFn = (req, next) => {
return next(req).pipe(
catchError(error => {
console.error('Error HTTP', error);
return throwError(() => error);
})
);
};
```
Configuración del interceptor:
```ts
import { provideHttpClient, withInterceptors } from '@angular/common/http';
provideHttpClient(
withInterceptors([errorInterceptor])
);
```
### Interceptor de autenticación (visión general)
Un interceptor de autenticación suele encargarse de añadir automáticamente un header `Authorization` con un token en cada petición saliente. Su lógica se centra en clonar la petición original y añadir el encabezado correspondiente.
### Estados de carga
```ts
loading = false;
cargarRecursos() {
this.loading = true;
this.recursosService.obtenerRecursos().subscribe({
next: data => this.recursos = data,
error: () => this.loading = false,
complete: () => this.loading = false
});
}
```
---
## Sesión 19 – Arquitectura de servicios
### Separación de responsabilidades
Un servicio debe tener una única responsabilidad clara. La lógica de acceso a datos no debe mezclarse con lógica de presentación ni con reglas complejas de negocio.
### Servicio genérico de acceso HTTP
```ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import config from '../config.json';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ApiService {
private apiBase = config.apiBase;
constructor(private http: HttpClient) {}
private buildUrl(params: Record<string, any>): string {
let url = this.apiBase;
Object.values(params).forEach(value => {
url += `/${value}`;
});
return url;
}
get<T>(params: Record<string, any>): Observable<T> {
return this.http.get<T>(this.buildUrl(params));
}
post<T>(params: Record<string, any>, body: any): Observable<T> {
return this.http.post<T>(this.buildUrl(params), body);
}
patch<T>(params: Record<string, any>, body: any): Observable<T> {
return this.http.patch<T>(this.buildUrl(params), body);
}
delete<T>(params: Record<string, any>): Observable<T> {
return this.http.delete<T>(this.buildUrl(params));
}
}
```
### Uso desde un servicio de dominio
```ts
@Injectable({
providedIn: 'root'
})
export class RecursosService {
constructor(private api: ApiService) {}
listar() {
return this.api.get({ recursos: 'recursos' });
}
}
```
### Anti‑patrones comunes
* Servicios excesivamente grandes y con múltiples responsabilidades.
* Lógica HTTP directamente en los componentes.
* Duplicación de llamadas a la API en distintos servicios.
### Escalabilidad
Una arquitectura basada en servicios pequeños, bien definidos y apoyados en servicios genéricos facilita el mantenimiento y la evolución de la aplicación a largo plazo.
Clone repository

Índice

  • Inicio
  • Módulo 1. Fundamentos y arranque del proyecto
    • Módulo 1.1 Angular
    • Módulo 1.2 Estructura
    • Módulo 1.2 Arquitectura y conceptos base
  • Módulo 2. Componentes y reutilización
  • Módulo 3. Navegación y estructura de aplicación
  • Módulo 4. Servicios y comunicación con backend
  • Módulo 5. Gestión de estado (Stores)
  • Módulo 6. Calidad, optimización y cierre