En Angular, los Observables son una parte fundamental del manejo de datos asincrónicos. Los Observables son una característica de la biblioteca RxJS (Reactive Extensions for JavaScript) que Angular utiliza para manejar eventos y datos asincrónicos. En esta sección, aprenderemos qué son los Observables, cómo crearlos, sus operadores más comunes y cómo utilizarlos en una aplicación Angular.
¿Qué es un Observable?
Un Observable es una colección de valores o eventos futuros que pueden ser manejados de manera asincrónica. Los Observables son similares a las Promesas, pero son más poderosos y flexibles. Pueden emitir múltiples valores a lo largo del tiempo y permiten operaciones como map, filter, reduce, etc.
Características Clave de los Observables:
- Emisión de Múltiples Valores: A diferencia de las Promesas, los Observables pueden emitir múltiples valores a lo largo del tiempo.
- Cancelación: Los Observables pueden ser cancelados, lo que es útil para evitar fugas de memoria.
- Operadores: RxJS proporciona una amplia gama de operadores para transformar, filtrar y combinar Observables.
Creación de Observables
Para crear un Observable, utilizamos la función Observable.create
o los métodos de creación proporcionados por RxJS como of
, from
, interval
, etc.
Ejemplo Básico de Creación de un Observable
import { Observable } from 'rxjs'; const observable = new Observable(subscriber => { subscriber.next('Hello'); subscriber.next('World'); subscriber.complete(); }); observable.subscribe({ next(x) { console.log(x); }, error(err) { console.error('Error: ' + err); }, complete() { console.log('Completed'); } });
Explicación del Código:
- Creación del Observable: Utilizamos
new Observable
y pasamos una función que recibe unsubscriber
. - Emisión de Valores: Utilizamos
subscriber.next
para emitir valores. - Completar el Observable: Utilizamos
subscriber.complete
para indicar que no se emitirán más valores. - Suscripción al Observable: Utilizamos
observable.subscribe
para recibir los valores emitidos.
Operadores Comunes de RxJS
RxJS proporciona una amplia gama de operadores que nos permiten transformar, filtrar y combinar Observables. Algunos de los operadores más comunes son:
map
Transforma cada valor emitido por el Observable.
import { of } from 'rxjs'; import { map } from 'rxjs/operators'; const numbers = of(1, 2, 3, 4, 5); const squaredNumbers = numbers.pipe(map(x => x * x)); squaredNumbers.subscribe(x => console.log(x));
filter
Filtra los valores emitidos por el Observable.
import { of } from 'rxjs'; import { filter } from 'rxjs/operators'; const numbers = of(1, 2, 3, 4, 5); const evenNumbers = numbers.pipe(filter(x => x % 2 === 0)); evenNumbers.subscribe(x => console.log(x));
mergeMap
Combina múltiples Observables en uno solo.
import { of } from 'rxjs'; import { mergeMap } from 'rxjs/operators'; const letters = of('a', 'b', 'c'); const result = letters.pipe( mergeMap(letter => of(letter + '1', letter + '2')) ); result.subscribe(x => console.log(x));
Uso de Observables en Angular
En Angular, los Observables se utilizan comúnmente para manejar datos asincrónicos, como solicitudes HTTP, eventos de usuario y flujos de datos en tiempo real.
Ejemplo: Uso de Observables con el Cliente HTTP
import { HttpClient } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; @Component({ selector: 'app-data', template: ` <div *ngIf="data$ | async as data"> <pre>{{ data | json }}</pre> </div> ` }) export class DataComponent implements OnInit { data$: Observable<any>; constructor(private http: HttpClient) {} ngOnInit() { this.data$ = this.http.get('https://api.example.com/data'); } }
Explicación del Código:
- Inyección del HttpClient: Inyectamos el servicio
HttpClient
en el constructor del componente. - Solicitud HTTP: Realizamos una solicitud HTTP GET y asignamos el Observable resultante a
data$
. - Uso del Async Pipe: Utilizamos el
async
pipe en la plantilla para suscribirnos automáticamente al Observable y mostrar los datos.
Ejercicio Práctico
Ejercicio:
Crea un componente Angular que realice una solicitud HTTP a una API pública y muestre los datos en la plantilla. Utiliza operadores de RxJS para transformar los datos antes de mostrarlos.
Solución:
import { HttpClient } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Component({ selector: 'app-user-list', template: ` <ul> <li *ngFor="let user of users$ | async"> {{ user.name }} ({{ user.email }}) </li> </ul> ` }) export class UserListComponent implements OnInit { users$: Observable<any>; constructor(private http: HttpClient) {} ngOnInit() { this.users$ = this.http.get('https://jsonplaceholder.typicode.com/users') .pipe( map((users: any[]) => users.map(user => ({ name: user.name, email: user.email }))) ); } }
Explicación del Código:
- Solicitud HTTP: Realizamos una solicitud HTTP GET a una API pública.
- Transformación de Datos: Utilizamos el operador
map
para transformar los datos antes de asignarlos ausers$
. - Mostrar Datos: Utilizamos el
async
pipe yngFor
para mostrar los datos en la plantilla.
Conclusión
En esta sección, hemos aprendido qué son los Observables, cómo crearlos, algunos operadores comunes de RxJS y cómo utilizarlos en una aplicación Angular. Los Observables son una herramienta poderosa para manejar datos asincrónicos y eventos en Angular, y su comprensión es crucial para desarrollar aplicaciones Angular robustas y eficientes.
En el siguiente módulo, exploraremos la gestión de estado en Angular, una técnica avanzada que nos permitirá manejar el estado de nuestra aplicación de manera más eficiente y escalable.
Curso de Angular 2+
Módulo 1: Introducción a Angular
- ¿Qué es Angular?
- Configuración del Entorno de Desarrollo
- Tu Primera Aplicación Angular
- Arquitectura de Angular
Módulo 2: Conceptos Básicos de TypeScript
- Introducción a TypeScript
- Variables y Tipos de Datos en TypeScript
- Funciones y Funciones Flecha
- Clases e Interfaces
Módulo 3: Componentes y Plantillas
- Creación de Componentes
- Plantillas de Componentes
- Estilos de Componentes
- Interacción entre Componentes
Módulo 4: Directivas y Pipes
Módulo 5: Servicios e Inyección de Dependencias
- Introducción a los Servicios
- Creación y Uso de Servicios
- Inyección de Dependencias
- Inyectores Jerárquicos
Módulo 6: Enrutamiento y Navegación
Módulo 7: Formularios en Angular
- Formularios Basados en Plantillas
- Formularios Reactivos
- Validación de Formularios
- Formularios Dinámicos
Módulo 8: Cliente HTTP y Observables
- Introducción al Cliente HTTP
- Realizando Solicitudes HTTP
- Manejo de Respuestas HTTP
- Uso de Observables
Módulo 9: Gestión de Estado
- Introducción a la Gestión de Estado
- Uso de Servicios para la Gestión de Estado
- NgRx Store
- NgRx Effects