signals + rxjs

<< Pipe async Resource API >>

La introducción de la API de señales en Angular no está destinada a reemplazar a los observables (rxjs) en Angular, sino a convivir con ellos. Aunque es cierto que en muchas ocasiones, las señales hacen que la necesidad del uso de observables, si queremos hacer uso de los principios de la programación reactiva, se reduzca bastante.

Se puede generar un observable a partir de una señal con la función toObservable. Este observable emitirá un nuevo valor cada vez que el valor de la señal cambie. De esta manera podemos utilizar las funciones de la librería rxjs para operar con estos valores.

También se puede hacer la operación inversa. Generar una señal a partir de un observable con la función toSignal. Esta función genera una señal de solo lectura que se suscribe al observable y almacena el último valor emitido por el mismo. 

Aquí podemos ver un ejemplo de como filtrar los productos utilizando funciones de la librería rxjs, combinando los últimos valores (combineLatest) del array de productos y la cadena de búsqueda como observables, y devolviendo el array de productos ya filtrados. Finalmente, se genera una señal (filteredProducts) a partir del observable que filtra esos productos. Esta señal será lo que utilicemos en la plantilla.

export class ProductsPageComponent {
  //...
  search = signal('');

  products = signal<Product[]>([]);
  
  filteredProducts$ = combineLatest([
    toObservable(this.products),
    toObservable(this.search),
  ]).pipe(
    map(([products, search]) => {
      return search
        ? products.filter((p) =>
            p.description.toLowerCase().includes(this.search().toLowerCase())
          )
        : products;
    })
  );

  filteredProducts = toSignal(this.filteredProducts$, {initialValue: []});
  //...
}

El código de arriba sirve como demostración de la interoperabilidad entre señales y la librería rxjs. La solución usando computed que hicimos en su momento es más limpia para este caso de uso, por lo que seguiremos con la solución anterior (con computed) para continuar con el curso.

<< Pipe async Resource API >>