Reaccionando a las interacciones del usuario con Signals

Ahora que tenemos Signals con Angular 16, la pregunta es cómo manejamos flujos de datos asíncronos con interacciones del usuario.

Es posible que sepas de la idea de un Action Streams , que Deborah Kurata, si no me equivoco, inventó, y estos representan las interacciones del usuario.

Para recapitular, la idea es crear un Observable a partir de un BehaviorSubject previamente definido que luego se actualizaría basado con las interacciones del usuario.

selectedCompany = new BehaviorSubjectstring>(”);

selectedCompanyAction$ = this.selectedCompany.asObservable();

selectCompany(value: Event)
const newValue = (value.target as HTMLSelectElement).value;
this.selectedCompany.next(newValue);
}

Gracias a crear un nuevo Observable a partir de la interacción del usuario, ahora puedes reaccionar a cambios hechos por el usuario, cargar más datos o mezclarlo con otros flujos asíncronos (Observable).

public filteredUsers$ = combineLatest([
this.manageUsersFacade.users$,
this.selectedCompanyAction$,
]).pipe(
map([users, company]) =>
company === ”? users: users.filter((user) => user.company === company)
)
);

El patrón de crear “Action Stream” fue muy efectivo y ayudó a mejorar la detección de cambios, ya que todo podía ser tratado como un Observable y podías confiar en la | asyncpara manejar los datos y evitar estar usar subscribe en cada uno de los observables que tienes.

Muestra como el “Action Stream” filtra los datos basado en la compañia que selecciono el usuario

Y entonces, ¿cómo se logra esto con Signals?

signal es un envoltorio alrededor de un valor que puede notificar a los consumidores interesados cuando ese valor cambia. Las señales pueden contener cualquier valor, desde primitivas simples hasta estructuras de datos complejas.

La primera parte consiste en transformar el “Action Stream” a un Signal. Para hacer esto, puedes convertir el observable usando la función toSignal o selectSignal si estás utilizando NgRx.

const usersSignal = toSignal(this.usersApiService.list());

users = this.store.selectSignal(selectAllUsers)

Luego, para crear la “Action Signal”, debemos declararla con un valor inicial y modificarla una vez que el usuario realice un cambio:

selectedCompany = signal<string>(”);

selectCompany(value: Event){
const newValue = (value.target as HTMLSelectElement).value;
this.selectedCompany.set(newValue);
}

El paso final es reemplazar el combineLatest que usábamos cuando trabajábamos con observables. Para hacer esto, vamos a utilizar el método computed que lee valores de ambos flujos y crea una nueva señal cada vez que alguno de ellos cambia. Así es cómo queda:

//👇 Crea la `Signal` que tiene los usuarios filtrados
public filteredUsers = computed(() => {

// 👇 Signal con los usuarios que vienen del API
const users = this.manageUsersFacade.users();

// 👇 “Action Signal” para las interacciones del usuario
const company = this.selectedCompany();

return company === ”
? users
: users.filter((user) => user.company === company);
});

Conclusión

Puedes declarar “Action Signals” que se actualiza cada vez que hay una interacción del usuario y utilizar compute para crear nuevas señales a partir de otras, al mismo tiempo que disfrutas de los beneficios de tener un código más eficiente sin observables y suscripciones.

Aquí tienes un ejemplo de código:

ng-demos/ngrx-with-signals.component.ts at main · alfredoperez/ng-demos

Ve mas de mi en Twitter o en mi website

Reaccionando a las interacciones del usuario con Signals was originally published in ngconf on Medium, where people are continuing the conversation by highlighting and responding to this story.

Leave a Comment

Your email address will not be published. Required fields are marked *