2

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?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
David
  • 614
  • 5
  • 20

1 Answers1

4

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

Manar Gul
  • 289
  • 4
  • 7
Andrei
  • 10,117
  • 13
  • 21
  • Its working, thanks! btw I have to say in the final subscribe the `response` parameter should be named `result` to fit the `result.data` – David Dec 11 '19 at 14:13