@anexia/ngx-loading-tools
Version:
This library provides a toolset for common loading state management, by providing hackable Loading Strategies and a Http Interceptor.
136 lines (126 loc) • 5.69 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, Inject } from '@angular/core';
import { throwError, BehaviorSubject, of } from 'rxjs';
import { tap, catchError, finalize, distinctUntilChanged, shareReplay, switchMap } from 'rxjs/operators';
import { __decorate } from 'tslib';
import { Memoize } from 'typescript-memoize';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
const LOADING_STRATEGY = new InjectionToken('Loading strategy token');
const INSPECT_LOADING_INTERCEPTOR = new InjectionToken('specifies if interceptor console logs are active', {
factory() {
return false;
}
});
class WebServiceLoadingInterceptor {
constructor(strategies, inspectLoadingInterceptor) {
this.strategies = strategies;
this.inspectLoadingInterceptor = inspectLoadingInterceptor;
}
intercept(request, delegate) {
if (!this.strategies) {
return delegate.handle(request);
}
// run loading strategy matcher against request
const matchingStrategies = this.strategies.filter(matchStrategy => matchStrategy.matcher.match(request));
if (this.inspectLoadingInterceptor) {
console.log(request, matchingStrategies, this.strategies);
}
// if no loading strategy matches
if (matchingStrategies.length === 0) {
return delegate.handle(request);
}
let requestCancelled = true;
return delegate.handle(request).pipe(tap((httpEvent) => {
if (this.inspectLoadingInterceptor) {
console.log(httpEvent, request, matchingStrategies);
}
if ((httpEvent === null || httpEvent === void 0 ? void 0 : httpEvent.type) === 4) {
requestCancelled = false;
this.stopStrategies(matchingStrategies, request);
}
if ((httpEvent === null || httpEvent === void 0 ? void 0 : httpEvent.type) === 0) {
matchingStrategies.forEach(matchingStrategy => matchingStrategy.handler.start(request));
}
}), catchError(error => {
if (this.inspectLoadingInterceptor) {
console.error(error, request, matchingStrategies);
}
requestCancelled = false;
this.stopStrategies(matchingStrategies, request);
return throwError(error);
}), finalize(() => {
if (this.inspectLoadingInterceptor) {
console.log('finalize', request, matchingStrategies);
}
if (requestCancelled) {
this.stopStrategies(matchingStrategies, request);
}
}));
}
stopStrategies(matchingStrategies, request) {
matchingStrategies.forEach(matchingStrategy => matchingStrategy.handler.stop(request));
}
}
WebServiceLoadingInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.3", ngImport: i0, type: WebServiceLoadingInterceptor, deps: [{ token: LOADING_STRATEGY }, { token: INSPECT_LOADING_INTERCEPTOR }], target: i0.ɵɵFactoryTarget.Injectable });
WebServiceLoadingInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.3", ngImport: i0, type: WebServiceLoadingInterceptor, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.3", ngImport: i0, type: WebServiceLoadingInterceptor, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [LOADING_STRATEGY]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [INSPECT_LOADING_INTERCEPTOR]
}] }]; } });
class LoadingHandler {
constructor() {
this._loadingState = new BehaviorSubject(false);
this.isLoading$ = this._loadingState.asObservable().pipe(distinctUntilChanged(), shareReplay(1));
}
start(request) {
this._loadingState.next(true);
}
stop(request) {
this._loadingState.next(false);
}
}
class DistinctLoadingHandler {
constructor(selector) {
this.selector = selector;
this._loadingStateSubject = new BehaviorSubject({});
}
start(request) {
this._updateState(this.selector(request), true);
}
stop(request) {
this._updateState(this.selector(request), false);
}
isLoading$(requestSelector) {
return this._loadingStateSubject.asObservable().pipe(switchMap(currentState => {
if (!currentState.hasOwnProperty(requestSelector)) {
return of(false);
}
return of(currentState[requestSelector]);
}), distinctUntilChanged(), shareReplay(1));
}
_updateState(requestId, value) {
const currentState = this._loadingStateSubject.getValue();
const newState = Object.assign(Object.assign({}, currentState), { [requestId]: value });
this._loadingStateSubject.next(newState);
}
}
__decorate([
Memoize((requestSelector) => requestSelector)
], DistinctLoadingHandler.prototype, "isLoading$", null);
function provideInterceptorConfig() {
return { provide: HTTP_INTERCEPTORS, useExisting: WebServiceLoadingInterceptor, multi: true };
}
/*
* Public API Surface of ngx-loading-tools
*/
/**
* Generated bundle index. Do not edit.
*/
export { DistinctLoadingHandler, INSPECT_LOADING_INTERCEPTOR, LOADING_STRATEGY, LoadingHandler, WebServiceLoadingInterceptor, provideInterceptorConfig };
//# sourceMappingURL=anexia-ngx-loading-tools.js.map