Skip to content

Commit ef12cdb

Browse files
committed
Feature request : Add possibility to filter by HTTP headers
1 parent 1d6f2ec commit ef12cdb

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

src/lib/components/spinner/spinner.component.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ export class SpinnerComponent implements OnDestroy, OnInit {
3434
@Input()
3535
public filteredMethods: string[] = [];
3636
@Input()
37+
public filteredHeaders: string[] = [];
38+
@Input()
3739
public debounceDelay = 0;
3840
@Input()
3941
public minDuration = 0;
@@ -68,6 +70,11 @@ export class SpinnerComponent implements OnDestroy, OnInit {
6870
throw new TypeError('`filteredMethods` must be an array.');
6971
}
7072
this.pendingInterceptorService.filteredMethods = this.filteredMethods;
73+
74+
if (!(this.filteredHeaders instanceof Array)) {
75+
throw new TypeError('`filteredHeaders` must be an array.');
76+
}
77+
this.pendingInterceptorService.filteredHeaders = this.filteredHeaders;
7178
}
7279

7380
ngOnDestroy(): void {

src/lib/services/pending-interceptor.service.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export class PendingInterceptorService implements HttpInterceptor {
2020
private _pendingRequestsStatus: ReplaySubject<boolean> = new ReplaySubject<boolean>(1);
2121
private _filteredUrlPatterns: RegExp[] = [];
2222
private _filteredMethods: string[] = [];
23+
private _filteredHeaders: string[] = [];
2324
private _forceByPass: boolean;
2425

2526
/** @deprecated Deprecated in favor of pendingRequestsStatus$ */
@@ -43,6 +44,10 @@ export class PendingInterceptorService implements HttpInterceptor {
4344
this._filteredMethods = httpMethods;
4445
}
4546

47+
set filteredHeaders(value: string[]) {
48+
this._filteredHeaders = value;
49+
}
50+
4651
set forceByPass(value: boolean) {
4752
this._forceByPass = value;
4853
}
@@ -59,9 +64,16 @@ export class PendingInterceptorService implements HttpInterceptor {
5964
});
6065
}
6166

67+
private shouldBypassHeader(req: HttpRequest<any>): boolean {
68+
return this._filteredHeaders.some(e => {
69+
return req.headers.has(e);
70+
});
71+
}
72+
6273
private shouldBypass(req: HttpRequest<any>): boolean {
6374
return this.shouldBypassUrl(req.urlWithParams)
6475
|| this.shouldBypassMethod(req)
76+
|| this.shouldBypassHeader(req)
6577
|| this._forceByPass;
6678
}
6779

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,23 @@ describe('SpinnerComponent', () => {
160160
}
161161
)));
162162

163+
it('should not show the spinner if the request is filtered by HTTP header', fakeAsync(inject(
164+
[HttpClient, HttpTestingController], (http: HttpClient, httpMock: HttpTestingController) => {
165+
component.filteredHeaders.push('header-to-filter');
166+
fixture.detectChanges();
167+
168+
http.get('/fake', {
169+
headers: {
170+
'header-to-filter': 'value'
171+
}
172+
}).subscribe();
173+
174+
tick();
175+
expect(component.isSpinnerVisible).toBeFalsy();
176+
httpMock.expectOne('/fake').flush({});
177+
}
178+
)));
179+
163180
it('should take care of query strings in filteredUrlPatterns', fakeAsync(inject(
164181
[HttpClient, HttpTestingController], (http: HttpClient, httpMock: HttpTestingController) => {
165182
component.filteredUrlPatterns.push('bar');
@@ -219,6 +236,30 @@ describe('SpinnerComponent', () => {
219236
}
220237
)));
221238

239+
it('should correctly filter by HTTP header with several requests', fakeAsync(inject(
240+
[HttpClient, HttpTestingController], (http: HttpClient, httpMock: HttpTestingController) => {
241+
component.filteredHeaders.push('My-HeAdER');
242+
fixture.detectChanges();
243+
244+
http.get('/12345', {
245+
headers: {
246+
'my-header': 'value'
247+
}
248+
}).subscribe();
249+
tick();
250+
expect(component.isSpinnerVisible).toBeFalsy();
251+
httpMock.expectOne('/12345').flush({});
252+
253+
http.get('/fake').subscribe();
254+
tick();
255+
expect(component.isSpinnerVisible).toBeTruthy();
256+
httpMock.expectOne('/fake').flush({});
257+
258+
tick();
259+
expect(component.isSpinnerVisible).toBeFalsy();
260+
}
261+
)));
262+
222263
it('should throw an error if filteredUrlPatterns is not an array', () => {
223264
component.filteredUrlPatterns = null;
224265
expect(() => fixture.detectChanges()).toThrow(new Error('`filteredUrlPatterns` must be an array.'));
@@ -229,6 +270,11 @@ describe('SpinnerComponent', () => {
229270
expect(() => fixture.detectChanges()).toThrow(new Error('`filteredMethods` must be an array.'));
230271
});
231272

273+
it('should throw an error if filteredHeaders is not an array', () => {
274+
component.filteredHeaders = null;
275+
expect(() => fixture.detectChanges()).toThrow(new Error('`filteredHeaders` must be an array.'));
276+
});
277+
232278
it('should show the spinner even if the component is created after the HTTP request is performed', fakeAsync(inject(
233279
[HttpClient, HttpTestingController], (http: HttpClient, httpMock: HttpTestingController) => {
234280
http.get('/fake').subscribe();

0 commit comments

Comments
 (0)