I've built a loading spinner component in Angular 2 that I'd like to trigger before http requests are made and disable when they're done. The problem is that each time the user changes an input (checks of of a box, types into the input box), the http request fires. This means a lot of requests, and the overlay is coming up constantly. I'd like to wait a set period of time (half a second?) after an input is triggered before triggering the http request, giving the user time to put in other inputs. I've read up a bit on debounce, but as far as I can see, that's for time waiting before making another request? And as far as I can see, that's just a buffer time between requests.
Basically, right now, I have a component that handles my inputs. When an input is changed (checkboxes right now), the following code is triggered:
@Output() filtersChanged = new EventEmitter();
emitFilters(): void {
this.filtersChanged.emit(this.filters);
}
Which through an intermediary step, sets off my http request:
getEvents(filters): Observable<Event[]> {
this.loadingSpinnerService.showLoadingSpinner();
let params: URLSearchParams = new URLSearchParams();
params.set('types', filters.types.join(','));
params.set('dates', filters.dates.join(','));
return this.http
.get('//api.dexcon.local/getEvents.php', { search: params })
.map((response: Response) => {
return response.json().events;
});
}
In Angular 1, I would have put it in a timeout which refreshed each time a user affected an input, so it'd trigger a set time after the final input was touched. Is this the best way to do it in Angular 2 as well? From my reading, debounce locks out a request from happening too close to a second request, but I'm wondering how to best prevent a request from happening after an action is taken for a given period of time.
The easiest way to accomplish what you're after is to set up a Subject (I'm assuming you have access to Rxjs here). Initialize one in your component:
inputSubject: Subject<string> = new Subject<string>();
Since a Subject is both an observer and an observable, you're going to want to set up a subscription to listen for changes. Here's where you can apply your debounce.
this.subscription = this.inputSubject.asObservable()
.debounceTime(1000)
.subscribe(x => this.filtersChanged.emit(this.filters));
Now, in your emitFilters() function instead of directly emitting, push the value onto the Subject.
this.inputSubject.next(newValue);
Don't forget to store your subscription as a member of your component class and dispose of it properly in your OnDestroy().
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With