Skip to content

Commit

Permalink
ISSUE-90: Better handling of synchronous (sequential) requests
Browse files Browse the repository at this point in the history
* added support for `extraDuration` feature
* added test for `extraDuration` feature
* `extraDuration` should delay spinner hiding at specified time (in millis), this should help to avoid spinner blinking on sequential requests (when crafting of one request depends on data from previous request, so that between those request may arrive ~5ms gap)
  • Loading branch information
gnom7 committed Sep 16, 2018
1 parent 78ae58b commit 874ac14
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/lib/components/ng-http-loader.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,16 @@ export class NgHttpLoaderComponent implements OnDestroy, OnInit {
@Input()
public minDuration = 0;
@Input()
public extraDuration = 0;
@Input()
public entryComponent: any = null;

constructor(private pendingInterceptorService: PendingInterceptorService, private spinnerVisibilityService: SpinnerVisibilityService) {
this.subscriptions = merge(
this.pendingInterceptorService.pendingRequestsStatus$.pipe(
debounce(h => this.handleDebounceDelay(h)),
delayWhen(h => this.handleMinDuration(h))
delayWhen(h => this.handleMinDuration(h)),
debounce(h => this.handleExtraDuration(h)),
),
this.spinnerVisibilityService.visibilityObservable$,
)
Expand Down Expand Up @@ -124,6 +127,13 @@ export class NgHttpLoaderComponent implements OnDestroy, OnInit {
return timer(this.minDuration - (Date.now() - this.startTime));
}

private handleExtraDuration(hasPendingRequests: boolean): Observable<number | never> {
if (this.extraDuration && !hasPendingRequests) {
return timer(this.extraDuration);
}
return EMPTY;
}

private shouldInitStartTime(): boolean {
return !this.isSpinnerVisible;
}
Expand Down
34 changes: 34 additions & 0 deletions src/test/components/ng-http-loader.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,40 @@ describe('NgHttpLoaderComponent', () => {
}
)));

it('should handle the extra spinner duration for multiple HTTP requests ran one after the others', fakeAsync(inject(
[HttpClient, HttpTestingController], (http: HttpClient, httpMock: HttpTestingController) => {
component.extraDuration = 10;

function runQuery(url: string): Observable<any> {
return http.get(url);
}

runQuery('/fake').subscribe();
const firstRequest = httpMock.expectOne('/fake');

tick(1000);
expect(component.isSpinnerVisible).toBeTruthy();

// the first HTTP request is finally over, the spinner is still visible for at least 10ms
firstRequest.flush({});
tick(5);
expect(component.isSpinnerVisible).toBeTruthy();

// But 5 ms after the first HTTP request has finished, a second HTTP request has been launched
runQuery('/fake2').subscribe();
const secondRequest = httpMock.expectOne('/fake2');

// After 700ms, the second http request ends. The spinner is still visible
tick(700);
secondRequest.flush({});
expect(component.isSpinnerVisible).toBeTruthy();

// 10ms later, the spinner should be hidden (extraDuration)
tick(10);
expect(component.isSpinnerVisible).toBeFalsy();
}
)));

it('should still display the spinner when the minimum duration is inferior to the HTTP request duration', fakeAsync(inject(
[HttpClient, HttpTestingController], (http: HttpClient, httpMock: HttpTestingController) => {
component.minDuration = 1000;
Expand Down

0 comments on commit 874ac14

Please sign in to comment.