In Angular, I'm currently writing a lot of Code repeatedly like this:
- I have service classes that return an
Observable<XYZ>
, that are sending requests to my backend - In my components I want to make sure that a request is only running once at the same time. So if a request takes a bit longer and the user hits a button again and again it doesn't start a new request. So my component has some
requestRunning
variable and invoking the service then looks like this:
myFunction() {
if (this.requestRunning) {
return;
}
this.requestRunning = true;
this.myService.callBackend().subscribe(
success => {
doSomething();
},
error => {
this.requestRunning = false;
},
_ => { // complete
this.requestRunning = false;
}
);
}
What I would prefer is something like an Observable which I can pass in the requestRunning
variable, and that sets it to true
if the Observable is subscribed to, and set to false
if the Observable finishes (complete/error).
Does somebody know a cool and DRY solution for this?
CodePudding user response:
you can use exhaustMap operator, this way you won't even need to maintain a variable to keep track of state, here the demo
though you'll need to change the way you are adding the listener on your button:
ngOnInit() {
const btn = this.button.nativeElement;
// this will produce outer observable
fromEvent(btn, "click")
.pipe(
exhaustMap(() => {
console.log("calling api...");
// this will produce inner observable, so exhaustMap will wait for inner
// observable to complete, until then it any emissions from outer observables are going to be ignored.
return this.appService.callApi();
})
)
.subscribe({
next: (apiResponse) => {
console.log("api response recieved");
}
});
}