typescript - Cómo interrumpir emisiones anteriores con el mismo evento en Angular 8
Tengo una aplicación que actualiza una tabla de datagrid cada vez que el usuario selecciona una fila en la tabla. Para hacerlo simple, aquí tengo un código de ejemplo:
componente-hijo.ts
public jsonData = {...} //api request
this.rowSelectedEvent.subscribe(() => {
this.refreshData(this.jsonData)
})
function refreshData(jsonData){
this.httpService.post(`${environment.BASE_URL}/api`, jsonData.payload).subscribe(
result => {
this.resultData = result.data
},
err => {
console.error(err)
}
)
}
El rowSelectedEvent se activa en el HTML cuando el usuario hace clic en una fila de una tabla. Esto sería un ejemplo:
app.component.html
<table>
<row (click)="notifyRowSelected"></row>
</table>
app.component.ts
@Output() rowSelectedEvent: EventEmitter<string> = new EventEmitter();
[...]
function notifyRowSelected(){
this.rowSelectedEvent.emit()
}
Este código funciona bien, recibe la respuesta de la API con los nuevos datos, dura alrededor de 4-5 segundos mientras el lado del servidor realiza sus cálculos y devuelve los nuevos valores. El problema aparece cuando el usuario hace clic en unas pocas filas repetidamente o en un corto período de tiempo porque la aplicación se vuelve loca y actualiza los datos múltiples veces en lugar de una sola vez (la última). Intenté usar unsubscribe() pero entonces no puedo suscribirme de nuevo, por lo que se pierde la funcionalidad. También he intentado switchMap() pero por alguna razón, cuando depuro el código, no entra en él.
La idea es detener los procesos pendientes cuando el usuario haga clic en una nueva fila, dejando que solo el último clic sea el que realice los cálculos y reciba la respuesta. ¿Algún consejo?
Respuesta #1
podrías usar el poder de rxjs para manejar eso
private makeCall(data) {
return this.http.post(...);
}
this.rowSelectedEvent.pipe(
map(() => this.jsonData),
distinctUntilChanged(), // to skip the same events in a row
switchMap((data) => this.makeCall(data)),
).subscribe((result) => this.resultData = result.data)
Todo el poder requerido reside en el operador switchMap. Cada vez que llega un nuevo evento, cancela la suscripción anterior (verás una solicitud roja cancelada en la pestaña de red si aún no se ha completado) y el controlador dentro de un subscribe solo recibirá el último evento
