@anexia/registry-loading-interceptor
Version:
This library provides an interceptor which maps Http Requests to a Loading State.
135 lines (125 loc) • 4.96 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, Inject, NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { BehaviorSubject, of, throwError } from 'rxjs';
import { switchMap, map, catchError, finalize, tap } from 'rxjs/operators';
const REQUEST_ID_GENERATOR = new InjectionToken('request.id.generator.strategy');
const REQUEST_FILTER = new InjectionToken('request.filter.strategy');
class UrlFragmentIdGenerator {
getIdentifier(fragment) {
return String(fragment).replace(/[:\/&?]/g, '_').trim();
}
createId(request) {
return this.getIdentifier(request.url);
}
}
class NoRequestFiltering {
exclude(request) {
return false;
}
}
class RegistryLoadingInterceptor {
constructor(requestIdGenerator, requestFilter) {
this.requestIdGenerator = requestIdGenerator;
this.requestFilter = requestFilter;
this.loadingDictionary = new Map();
this.stateChangeTrigger$ = new BehaviorSubject(false);
this.networkRequestCounter$ = new BehaviorSubject(0);
this.loadingState$ = this.stateChangeTrigger$
.asObservable()
.pipe(switchMap(() => of(this.loadingDictionary)));
this.isAnyRequestLoading$ = this.networkRequestCounter$
.asObservable()
.pipe(map(count => count > 0));
}
static mapEventTypeToLoading(event) {
return (event === null || event === void 0 ? void 0 : event.type) === 0;
}
intercept(request, delegate) {
let requestCancelled = true;
return delegate.handle(request)
.pipe(map((event) => {
if ((event === null || event === void 0 ? void 0 : event.type) === 4) {
requestCancelled = false;
}
return event;
}), this.mapHttpEventToLoadingCount$(), this.mapHttpEventToLoadingState$(request), catchError(error => {
requestCancelled = false;
this.updateLoadingCounter(false);
if (!this.requestFilter.exclude(request)) {
this.updateLoadingState(this.getRequestId(request), false);
}
return throwError(error);
}), finalize(() => {
if (requestCancelled) {
this.decrementCounter();
}
}));
}
mapHttpEventToLoadingState$(request) {
if (this.requestFilter.exclude(request)) {
return tap();
}
return tap(event => this.updateLoadingState(this.getRequestId(request), RegistryLoadingInterceptor.mapEventTypeToLoading(event)));
}
mapHttpEventToLoadingCount$() {
return tap(event => this.updateLoadingCounter(RegistryLoadingInterceptor.mapEventTypeToLoading(event)));
}
updateLoadingState(requestId, isLoading) {
this.loadingDictionary.set(requestId, isLoading);
this.stateChangeTrigger$.next(true);
}
updateLoadingCounter(isLoading) {
isLoading ? this.incrementCounter() : this.decrementCounter();
}
getRequestId(request) {
return this.requestIdGenerator.createId(request);
}
incrementCounter() {
this.networkRequestCounter$.next(this.networkRequestCounter$.value + 1);
}
decrementCounter() {
this.networkRequestCounter$.next(this.networkRequestCounter$.value - 1);
}
}
RegistryLoadingInterceptor.ɵprov = i0.ɵɵdefineInjectable({ factory: function RegistryLoadingInterceptor_Factory() { return new RegistryLoadingInterceptor(i0.ɵɵinject(REQUEST_ID_GENERATOR), i0.ɵɵinject(REQUEST_FILTER)); }, token: RegistryLoadingInterceptor, providedIn: "root" });
RegistryLoadingInterceptor.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] }
];
RegistryLoadingInterceptor.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [REQUEST_ID_GENERATOR,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [REQUEST_FILTER,] }] }
];
const defaultProviders = [
{
provide: REQUEST_ID_GENERATOR,
useClass: UrlFragmentIdGenerator,
},
{
provide: REQUEST_FILTER,
useClass: NoRequestFiltering
},
{
provide: HTTP_INTERCEPTORS,
useExisting: RegistryLoadingInterceptor,
multi: true
}
];
class RegistryLoadingInterceptorModule {
}
RegistryLoadingInterceptorModule.decorators = [
{ type: NgModule, args: [{
imports: [
HttpClientModule
],
providers: [defaultProviders]
},] }
];
/*
* Public API Surface of registry-loading-interceptor
*/
/**
* Generated bundle index. Do not edit.
*/
export { NoRequestFiltering, REQUEST_FILTER, REQUEST_ID_GENERATOR, RegistryLoadingInterceptor, RegistryLoadingInterceptorModule, UrlFragmentIdGenerator, defaultProviders };
//# sourceMappingURL=anexia-registry-loading-interceptor.js.map