I have an app that refreshes a datagrid table every time the user selects a row in the table. To make it simple here I have a sample code:
child-component.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)
}
)
}
The rowSelectedEvent
is triggered in the HTML when the user clicks on a row of a table. This would be an example:
app.component.html
<table>
<row (click)="notifyRowSelected"></row>
</table>
app.component.ts
@Output() rowSelectedEvent: EventEmitter<string> = new EventEmitter();
[...]
function notifyRowSelected(){
this.rowSelectedEvent.emit()
}
This code works fine, receives the API response with the new data, it lasts around 4-5 seconds that the server side make its calculations and returns the new values. The problem appears when the user clicks on a few rows repeatedly or in a small amount of time because the app goes crazy and refreshes the data multiple times instead of one time (the last one). I tried using unsubscribe()
but then I'm not able to subscribe again so the functionality is lost. I've also tried switchMap()
but for some reason when I debug the code it doesn't get into it.
The idea is to stop the pending processes when the user clicks on a new row letting just the last click being the one that make the calculations and receives the response. Any advice?
you could use the power of rxjs to handle that
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)
all the required power lies in switchMap
operator. Whenever new event comes it cancels the previous subscription(you will see canceled red request in a network tab if it is not complete yet) and handler inside of a subscribe will only receive the last event