Skip to content

Commit

Permalink
Merge pull request #9 from mpalourdio/requests_filter
Browse files Browse the repository at this point in the history
Add possibility to filter requests that shouldn't be caught by the interceptor.
  • Loading branch information
mpalourdio authored Aug 30, 2017
2 parents 94c2d02 + cafa0e6 commit 12b69a6
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 104 deletions.
9 changes: 9 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ You can too customize the background-color and the spinner type :
<spinner [backgroundColor]="'#ff0000'" [spinner]="Spinkit.skWave"></spinner>
```

You can filter the requests that shouldn't be caught by the interceptor by providing an array of regex patterns :
```xml
<spinner
[backgroundColor]="'#ff0000'"
[spinner]="Spinkit.skWave"
[filteredUrlPatterns]="['\\d', '[a-zA-Z]', 'my-api']>
</spinner>
```
The different spinners available are referenced in [this class](src/app/spinkits.ts).
## Requirements
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ng-http-loader",
"version": "0.2.0",
"version": "0.3.0",
"scripts": {
"prepare-deploy": "gulp inline-templates && gulp clean-dist && ngc -p tsconfig.ngc.json && gulp clean-tmp && gulp copy-all",
"test": "ng test --watch false"
Expand Down
29 changes: 23 additions & 6 deletions src/app/pending-interceptor.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import 'rxjs/add/observable/throw';
export class PendingInterceptorService implements HttpInterceptor {
private _pendingRequests = 0;
private _pendingRequestsStatus: Subject<boolean> = new Subject<boolean>();
private _filteredUrlPatterns: RegExp[] = [];

get pendingRequestsStatus(): Observable<boolean> {
return this._pendingRequestsStatus.asObservable();
Expand All @@ -29,11 +30,25 @@ export class PendingInterceptorService implements HttpInterceptor {
return this._pendingRequests;
}

get filteredUrlPatterns(): RegExp[] {
return this._filteredUrlPatterns;
}

private shouldBypass(url: string): boolean {
return this._filteredUrlPatterns.some(e => {
return e.test(url);
});
}

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this._pendingRequests++;
const shouldBypass = this.shouldBypass(req.url);

if (!shouldBypass) {
this._pendingRequests++;

if (1 === this._pendingRequests) {
this._pendingRequestsStatus.next(true);
if (1 === this._pendingRequests) {
this._pendingRequestsStatus.next(true);
}
}

return next.handle(req).map(event => {
Expand All @@ -43,10 +58,12 @@ export class PendingInterceptorService implements HttpInterceptor {
return Observable.throw(error);
})
.finally(() => {
this._pendingRequests--;
if (!shouldBypass) {
this._pendingRequests--;

if (0 === this._pendingRequests) {
this._pendingRequestsStatus.next(false);
if (0 === this._pendingRequests) {
this._pendingRequestsStatus.next(false);
}
}
});
}
Expand Down
37 changes: 37 additions & 0 deletions src/app/spinner/spinner.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,41 @@ describe('SpinnerComponent', () => {
expect(component.isSpinnerVisible).toBeFalsy();
})
);

it('should not show the spinner if the request is filtered',
inject(
[PendingInterceptorService, HttpClient, HttpTestingController],
(service: PendingInterceptorService, http: HttpClient, httpMock: HttpTestingController) => {
component.filteredUrlPatterns.push('fake');
fixture.detectChanges();

http.get('/fake').subscribe();
expect(component.isSpinnerVisible).toBeFalsy();
httpMock.expectOne('/fake').flush({});
})
);

it('should correctly filter with several requests and one pattern',
inject(
[PendingInterceptorService, HttpClient, HttpTestingController],
(service: PendingInterceptorService, http: HttpClient, httpMock: HttpTestingController) => {
component.filteredUrlPatterns.push('\\d');
fixture.detectChanges();

http.get('/12345').subscribe();
expect(component.isSpinnerVisible).toBeFalsy();
httpMock.expectOne('/12345').flush({});

http.get('/fake').subscribe();
expect(component.isSpinnerVisible).toBeTruthy();
httpMock.expectOne('/fake').flush({});
expect(component.isSpinnerVisible).toBeFalsy();
})
);

it('should throw an error if filteredUrlPatterns is not an array', () => {
component.filteredUrlPatterns = null;
expect(() => fixture.detectChanges())
.toThrow(new Error('`filteredUrlPatterns` must be an array.'));
});
});
18 changes: 16 additions & 2 deletions src/app/spinner/spinner.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import { Component, Input, OnDestroy } from '@angular/core';
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { Spinkit } from '../spinkits';
import { PendingInterceptorService } from '../pending-interceptor.service';
Expand All @@ -27,7 +27,7 @@ import { PendingInterceptorService } from '../pending-interceptor.service';
'./spinkit-css/sk-wave.css',
]
})
export class SpinnerComponent implements OnDestroy {
export class SpinnerComponent implements OnDestroy, OnInit {
public isSpinnerVisible: boolean;
private subscription: Subscription;
public Spinkit = Spinkit;
Expand All @@ -36,6 +36,8 @@ export class SpinnerComponent implements OnDestroy {
public backgroundColor: string;
@Input()
public spinner = Spinkit.skCubeGrid;
@Input()
public filteredUrlPatterns: string[] = [];

constructor(private pendingRequestInterceptorService: PendingInterceptorService) {
this.subscription = this.pendingRequestInterceptorService
Expand All @@ -45,6 +47,18 @@ export class SpinnerComponent implements OnDestroy {
});
}

ngOnInit(): void {
if (!(this.filteredUrlPatterns instanceof Array)) {
throw new TypeError('`filteredUrlPatterns` must be an array.');
}

if (!!this.filteredUrlPatterns.length) {
this.filteredUrlPatterns.forEach(e => {
this.pendingRequestInterceptorService.filteredUrlPatterns.push(new RegExp(e));
});
}
}

ngOnDestroy(): void {
this.subscription.unsubscribe();
}
Expand Down
Loading

0 comments on commit 12b69a6

Please sign in to comment.