Skip to content

Commit ae0ba91

Browse files
authored
Merge pull request #66 from mpalourdio/bypass
Prevent the http interceptor from being triggered when using SpinnerVisibilityService. Fixes #64
2 parents afc598c + c28647b commit ae0ba91

File tree

7 files changed

+67
-10
lines changed

7 files changed

+67
-10
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## v1.0.1
4+
5+
This release is a bug fix release. It prevents the ``PendingInterceptorService`` from being triggered when using the ``SpinnerVisibilityService``.
6+
See this [issue](https://github.com/mpalourdio/ng-http-loader/issues/64) for more details.
7+
38
## v1.0.0
49

510
This release introduces full support for angular 6 & RxJS 6.

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ If you want to use Angular 5, use versions **``0.4.0``** and above.
3232

3333
The latest compatible version with angular 5 is version **``0.9.1``**.
3434

35-
Versions above **``0.9.1``** are angular 6 / RxJS 6 compatible only.
35+
From version **``1.0.0``**, the module is angular 6 / RxJS 6 compatible only.
3636

3737
If you experience errors like below, **please double check the version you use.**
3838

@@ -154,7 +154,6 @@ You can define your own loader component in place of the built-in ones. The need
154154

155155
You can find some short examples [here](https://gist.github.com/mpalourdio/2c0bec03d610b24ff49db649fbb69a48) and [here](https://gist.github.com/mpalourdio/e05b4495de2abeeecfcf92d70e4ef93e).
156156

157-
158157
## Requests filtering
159158

160159
You can also filter the http requests that shouldn't be caught by the interceptor by providing **an array of regex patterns**:
@@ -166,6 +165,10 @@ You can also filter the http requests that shouldn't be caught by the intercepto
166165

167166
You can manually show and hide the spinner component if needed. You must use the ``SpinnerVisibilityService`` for this purpose.
168167

168+
Sometimes, when manually showing the spinner, an http request could be performed in background, and when finished, the spinner would automagically disappear.
169+
170+
**For this reason, when calling ``SpinnerVisibilityService#show()``, it prevents the http interceptor from being triggered unless you explicitly call ``SpinnerVisibilityService#hide()``.**
171+
169172
```typescript
170173
import { SpinnerVisibilityService } from 'ng-http-loader/services/spinner-visibility.service';
171174

@@ -179,6 +182,9 @@ export class MyComponent {
179182
constructor(private spinner: SpinnerVisibilityService) {
180183
// show the spinner
181184
spinner.show();
185+
//////////////
186+
// http requests performed between won't have any side effect on the spinner
187+
/////////////
182188
// hide the spinner
183189
spinner.hide();
184190
}

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ng-http-loader",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"scripts": {
55
"prepare-deploy": "gulp inline-templates && gulp clean-dist && ngc -p tsconfig.ngc.json && gulp clean-tmp && gulp copy-all",
66
"test": "ng test"
@@ -18,6 +18,7 @@
1818
"ng2",
1919
"ng4",
2020
"ng5",
21+
"ng6",
2122
"loader",
2223
"progressbar",
2324
"spinner",

src/services/pending-interceptor.service.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export class PendingInterceptorService implements HttpInterceptor {
1717
private _pendingRequests = 0;
1818
private _pendingRequestsStatus: ReplaySubject<boolean> = new ReplaySubject<boolean>(1);
1919
private _filteredUrlPatterns: RegExp[] = [];
20+
private _forceByPass: boolean;
2021

2122
get pendingRequestsStatus(): Observable<boolean> {
2223
return this._pendingRequestsStatus.asObservable();
@@ -30,16 +31,20 @@ export class PendingInterceptorService implements HttpInterceptor {
3031
return this._filteredUrlPatterns;
3132
}
3233

34+
set forceByPass(value: boolean) {
35+
this._forceByPass = value;
36+
}
37+
3338
private shouldBypassUrl(url: string): boolean {
3439
return this._filteredUrlPatterns.some(e => {
3540
return e.test(url);
3641
});
3742
}
3843

3944
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
40-
const shouldBypassUrl = this.shouldBypassUrl(req.urlWithParams);
45+
const shouldBypass = this.shouldBypassUrl(req.urlWithParams) || this._forceByPass;
4146

42-
if (!shouldBypassUrl) {
47+
if (!shouldBypass) {
4348
this._pendingRequests++;
4449

4550
if (1 === this._pendingRequests) {
@@ -55,7 +60,7 @@ export class PendingInterceptorService implements HttpInterceptor {
5560
return throwError(error);
5661
}),
5762
finalize(() => {
58-
if (!shouldBypassUrl) {
63+
if (!shouldBypass) {
5964
this._pendingRequests--;
6065

6166
if (0 === this._pendingRequests) {

src/services/spinner-visibility.service.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,36 @@
99

1010
import { Injectable } from '@angular/core';
1111
import { Observable, ReplaySubject } from 'rxjs';
12+
import { PendingInterceptorService } from './pending-interceptor.service';
1213

1314
@Injectable()
1415
export class SpinnerVisibilityService {
1516
private _visibilitySubject: ReplaySubject<boolean> = new ReplaySubject<boolean>(1);
1617

18+
constructor(private pendingInterceptorService: PendingInterceptorService) {
19+
}
20+
1721
get visibilityObservable(): Observable<boolean> {
1822
return this._visibilitySubject.asObservable();
1923
}
2024

2125
public show(): void {
26+
this.pendingInterceptorService.forceByPass = true;
2227
this._visibilitySubject.next(true);
2328
}
2429

2530
public hide(): void {
2631
this._visibilitySubject.next(false);
32+
this.pendingInterceptorService.forceByPass = false;
2733
}
2834
}
2935

30-
export function SpinnerVisibilityServiceFactory(): SpinnerVisibilityService {
31-
return new SpinnerVisibilityService();
36+
export function SpinnerVisibilityServiceFactory(pendingInterceptorService: PendingInterceptorService): SpinnerVisibilityService {
37+
return new SpinnerVisibilityService(pendingInterceptorService);
3238
}
3339

3440
export let SpinnerVisibilityServiceFactoryProvider = {
3541
provide: SpinnerVisibilityService,
36-
useFactory: SpinnerVisibilityServiceFactory
42+
useFactory: SpinnerVisibilityServiceFactory,
43+
deps: [PendingInterceptorService]
3744
};

test/components/spinner/spinner.component.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,4 +296,33 @@ describe('SpinnerComponent', () => {
296296
expect(component.isSpinnerVisible).toBeFalsy();
297297
}
298298
));
299+
300+
it('should keep the spinner visible even if an http request ends before calling \'hide\'', fakeAsync(inject(
301+
[SpinnerVisibilityService, HttpClient, HttpTestingController],
302+
(spinner: SpinnerVisibilityService, http: HttpClient, httpMock: HttpTestingController) => {
303+
// we manually show the spinner
304+
spinner.show();
305+
expect(component.isSpinnerVisible).toBeTruthy();
306+
// then an http request is performed
307+
http.get('/fake').subscribe();
308+
tick();
309+
expect(component.isSpinnerVisible).toBeTruthy();
310+
// the http request ends, but we want the spinner to be still visible
311+
httpMock.expectOne('/fake').flush({});
312+
tick();
313+
expect(component.isSpinnerVisible).toBeTruthy();
314+
315+
spinner.hide();
316+
// this time the spinner is not displayed anymore
317+
expect(component.isSpinnerVisible).toBeFalsy();
318+
319+
// the bypassPendingInterceptorService should be reset for next http requests
320+
http.get('/fake2').subscribe();
321+
tick();
322+
expect(component.isSpinnerVisible).toBeTruthy();
323+
httpMock.expectOne('/fake2').flush({});
324+
tick();
325+
expect(component.isSpinnerVisible).toBeFalsy();
326+
}
327+
)));
299328
});

test/services/spinner-visibility.service.spec.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@
88
*/
99

1010
import { inject, TestBed } from '@angular/core/testing';
11+
import { PendingInterceptorService } from '../../src/services/pending-interceptor.service';
1112
import { SpinnerVisibilityService } from '../../src/services/spinner-visibility.service';
1213

1314
describe('SpinnerVisibilityService', () => {
1415

1516
beforeEach(() => {
1617
TestBed.configureTestingModule({
17-
providers: [SpinnerVisibilityService]
18+
providers: [
19+
SpinnerVisibilityService,
20+
PendingInterceptorService,
21+
]
1822
});
1923
});
2024

0 commit comments

Comments
 (0)