Reactive Extensions for JavaScript, o RxJS, es una biblioteca de JavaScript que utiliza observables para la programación reactiva. Se puede utilizar con otras bibliotecas y frameworks de JavaScript, y se integra bien en Angular. Hoy hablaremos de RxJS y Angular, los beneficios de usar RxJS en Angular y cómo usarlos juntos.
¿Qué es RxJS?
El paradigma reactivo puede ser utilizado en muchos lenguajes diferentes a través del uso de bibliotecas reactivas. Estas bibliotecas son APIs descargadas que proporcionan funcionalidades para herramientas reactivas como observadores y operadores.
Reactive Extensions for JavaScript, o RxJS, es una biblioteca reactiva que se utiliza para implementar la programación reactiva para tratar con la implementación asíncrona, las devoluciones de llamada y los programas basados en eventos. Se puede utilizar en el navegador o con Node.js.
RxJS tiene algunas características principales que ayudan a manejar la implementación asincrónica:
Observable
Los observables de RxJS permiten publicar eventos. Los observables tienen dos métodos: suscribirse y desuscribirse. Se ejecuta un observable suscribiéndose a él. Los observables modelan un flujo de eventos.
Observador
Un observador es un objeto con métodos next(), error() y complete() que es llamado cuando hay una interacción con el observable. Son los objetos que se suscriben a los observables.
Suscripción
Una suscripción al observable hará que éste se ejecute.
Operador
Un operador es una función que nos permite realizar ciertas acciones sobre los eventos ejecutados por los observables.
Asunto
Un sujeto es lo mismo que un EventEmitter. Es un observable que multiplica la información a los observadores.
Programador
Un planificador maneja la ejecución de las suscripciones.
La librería RxJS es excelente para manejar tareas asíncronas. Tiene una gran colección de operadores de filtrado, manejo de errores, condicional, creación, multidifusión, y más. Es compatible con JavaScript y TypeScript, y funciona bien con Angular.
Pros y contras de RxJS
Pros
RxJS es una herramienta potente y popular que sigue creciendo. Tiene más de 2 millones de repositorios dependientes en GitHub y más de 22 millones de descargas semanales de NPM. Echemos un vistazo a algunas de las razones por las que es tan popular:
- Flexibilidad: Se puede utilizar con otras bibliotecas y frameworks de JavaScript.
- Gran API: Con RxJS, puedes simplificar tu flujo de trabajo con flujos de datos asíncronos y ahorrar tiempo.
- Optimizado: Muchos desarrolladores lo han probado y mejorado.
- Extensibilidad: Está diseñado para permitir nuevas funcionalidades.
- Autosuficiente: RxJS no tiene dependencias de terceros.
- Comunidad útil: Los miembros de la comunidad RxJS se ayudan mutuamente a resolver problemas y a responder preguntas.
Contras
Como cualquier otra herramienta, RxJS tiene algunas desventajas. Echemos un vistazo a ellos:
- Depuración: La depuración de código con observables no siempre es sencilla.
- Inmutabilidad de los datos: La programación reactiva funciona mejor cuando se combina con la programación funcional.
- Dependencia de tslib: La única dependencia que tiene RxJS es tslib. Los detalles de la implementación interna no siempre están restringidos, lo que significa que se puede ver algún uso inadecuado de los modificadores de acceso.
RxJS en Angular
Veamos cómo puede funcionar RxJS en Angular. Vamos a construir una caja de entrada de número de teléfono.
Comencemos!
Generar un nuevo proyecto
Antes de empezar, vamos a instalar la CLI de Angular usando npm install -g @angular/cli. Una vez terminado, podemos empezar a trabajar en nuestra aplicación.
Ejecuta ng new rx-phone --routing en el directorio en el que quieras crear la aplicación.
También ejecutarás ng serve en la raíz de tu proyecto para disparar un servidor para la caja de entrada del número de teléfono.
Nota: El comando new crea una nueva aplicación Angular. El parámetro --routing le dice a ng que añada un enrutamiento con capacidad de observación para la aplicación.
Estilo con CSS
La aplicación que queremos construir utiliza el CSS de Bootsrap para el aspecto visual. Comenzaremos abriendo el archivo index.html. A continuación, vamos a traer el CSS y añadir la siguiente etiqueta al head del archivo:
(loaded from local server) -->
<link rel="stylesheet" href="http://localhost:3000/assets/bootstrap.min.css">
Verás un marcador de posición HTML en app.component.html. Elimínalo y añade esto en su lugar:
<div class="container">
<router-outlet></router-outlet>
</div>
Importar formularios reactivos
Dado que los formularios reactivos no se incluyen con Angular, tenemos que importarlos a nivel de aplicación.
Este es el aspecto que debería tener nuestro código:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ReactiveFormsModule } from '@angular/forms'; // <callout id="co.ng2reactiveforms.module1"/>
/* ... snip ... */
@NgModule({
imports: [
BrowserModule,
AppRoutingModule,
ReactiveFormsModule // <callout id="co.ng2reactiveforms.module2"/>
],
declarations: [
AppComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Generar un nuevo componente
- Ejecuta ng generate component phone-num y añade una declaración al módulo de enrutamiento.
- Inicia el servidor de Angular con ng serve.
- Añade una ruta a app-routing.module.ts para el nuevo componente.
{
path: 'phone',
component: PhoneNumComponent
},
Crear una entrada de teléfono
Abre phone-num.ts e importa FormControl y AbstractControl:
import { FormControl, AbstractControl } from '@angular/forms';
Crear una propiedad FormControl
Añade la siguiente línea como declaración a la clase PhoneNumComponent:
import { FormControl, AbstractControl } from '@angular/forms';
export class PhoneNumComponent implements OnInit {
phoneNumber = new FormControl();
Validar formularios
Necesitamos crear alguna validación para asegurarnos de que el usuario nos da un número de teléfono válido. Podemos utilizar una única regla de validación sincrónica para asegurarnos de que el usuario introduce un número de diez dígitos.
export class PhoneNumComponent implements OnInit {
phoneNumber = new FormControl('', [
(control: AbstractControl) => {
// remove any input that isn't a digit
const numDigits = control.value.replace(/[^\d]+/g, '').length;
// only working with US numbers for now, don't need a country code
if (numDigits === 10) { return null; }
if (numDigits > 10) {
return {
tooLong: { numDigits }
};
} else {
return {
tooShort: { numDigits }
};
}
}
]);
Mostrar mensajes de error
Cuando el número de teléfono insertado es válido, la función validadora devuelve null para mostrar que no hay ningún error.
Cuando hay un error, la función validadora devuelve un objeto. Ahora que estamos validando nuestro número de teléfono, vamos a actualizar la vista para mostrar la nueva información.
<input [formControl]="phoneNumber" />
<!-- (1) -->
<div *ngIf="phoneNumber.invalid">
<!-- (2) -->
<div *ngIf="(phoneNumber.dirty || phoneNumber.touched)">
<!-- (3) -->
<div *ngIf="phoneNumber.errors.tooLong">
Your phone number has too many digits!
You entered {{ phoneNumber.errors.tooLong.numDigits }}
digits (required: 10)
</div>
<div *ngIf="phoneNumber.errors.tooShort">
Your phone number is too short!
You entered {{ phoneNumber.errors.tooShort.numDigits }}
digits (required: 10)
</div>
</div>
</div>
Lo siguiente que podemos hacer es añadir detalles de estilo a las clases CSS para añadir pistas visuales al usuario. Por ahora, terminaremos el tutorial aquí.
Conclusión y próximos pasos
¡Felicidades por dar tus primeros pasos con RxJS en Angular! La librería RxJS puede ayudarte a manejar la implementación asíncrona de una manera flexible y eficiente. Todavía hay muchas cosas que aprender sobre la programación reactiva y RxJS, como por ejemplo
- Flujos observables
- BehaviorSubject
- Async Pipe
Y más..