fix: delete saving states

Parallel use of the same Api Service instance is likely to replace requestData
This commit is contained in:
2024-08-24 04:24:44 +03:00
parent 2871505591
commit fd5a1cb14f
9 changed files with 169 additions and 152 deletions

View File

@ -1,10 +1,10 @@
import {catchError, filter, mergeMap, Observable, retryWhen, switchMap, tap, timer} from "rxjs";
import {catchError, filter, mergeMap, Observable, retryWhen, switchMap, timer} from "rxjs";
import {HttpClient, HttpErrorResponse} from "@angular/common/http";
import {NotifyColor, OpenNotifyService} from "@service/open-notify.service";
import {environment} from "@environment";
import {Router} from "@angular/router";
import {Injectable} from "@angular/core";
import {RequestBuilder, RequestData, SetRequestBuilderAfterBuild} from "@api/RequestBuilder";
import {RequestBuilder, RequestData} from "@api/RequestBuilder";
import {TokenRefreshService} from "@service/token-refresh.service";
import {AuthToken} from "@service/auth.service";
@ -36,19 +36,16 @@ export enum AvailableVersion {
}
@Injectable()
export default abstract class ApiService implements SetRequestBuilderAfterBuild {
export default abstract class ApiService {
constructor(private http: HttpClient, private notify: OpenNotifyService, private router: Router, protected tokenRefreshService: TokenRefreshService) {
}
private apiUrl = environment.apiUrl;
protected abstract basePath: string;
protected abstract version: AvailableVersion;
private request: RequestData = RequestBuilder.getStandardRequestData();
public static readonly tokenKey = 'auth_token';
public setRequestBuilder(request: RequestData): void {
this.request = request;
}
public static readonly tokenKey = 'auth_token';
private static addQuery(endpoint: string, queryParams?: Record<string, string | number | boolean | Array<any> | null> | null): string {
const url = new URL(endpoint);
@ -72,73 +69,81 @@ export default abstract class ApiService implements SetRequestBuilderAfterBuild
return parts.map(part => part.replace(/(^\/+|\/+$)/g, '')).join('/');
}
protected get combinedUrl() {
return ApiService.addQuery(ApiService.combineUrls(this.apiUrl, AvailableVersion[this.version], this.basePath, this.request.endpoint), this.request.queryParams);
protected combinedUrl(request: RequestData) {
return ApiService.addQuery(ApiService.combineUrls(this.apiUrl, AvailableVersion[this.version], this.basePath, request.endpoint), request.queryParams);
}
private makeHttpRequest<Type>(method: 'get' | 'post' | 'delete' | 'put'): Observable<Type> {
const doneEndpoint = this.combinedUrl;
private sendHttpRequest<Type>(method: 'get' | 'post' | 'delete' | 'put', request: RequestData): Observable<Type> {
const doneEndpoint = this.combinedUrl(request);
return this.tokenRefreshService.getTokenRefreshing$().pipe(
filter(isRefreshing => !isRefreshing),
switchMap(() =>
this.http.request<Type>(method, doneEndpoint, {
withCredentials: this.request.withCredentials,
headers: this.request.httpHeaders,
body: this.request.data
}).pipe(
tap(_ => this.request = RequestBuilder.getStandardRequestData()),
retryWithInterval<Type>(),
catchError(error => {
if (!this.request.silenceMode)
this.handleError(error);
return this.http.request<Type>(method, doneEndpoint, {
withCredentials: request.withCredentials,
headers: request.httpHeaders,
body: request.data
}).pipe(
retryWithInterval<Type>(),
catchError(error => {
if (!request.silenceMode)
this.handleError(error);
this.request = RequestBuilder.getStandardRequestData();
throw error;
})
)
)
throw error;
})
);
}
private makeHttpRequest<Type>(method: 'get' | 'post' | 'delete' | 'put', request: RequestData): Observable<Type> {
console.log(request);
if (request.needAuth)
return this.tokenRefreshService.getTokenRefreshing$().pipe(
filter(isRefreshing => !isRefreshing),
switchMap(() => {
console.log("I'm here!");
const token = localStorage.getItem(ApiService.tokenKey);
if (token) {
const authToken = AuthToken.httpHeader((JSON.parse(token) as AuthToken));
authToken.keys().forEach(key => request.httpHeaders = request.httpHeaders.append(key, authToken.get(key) ?? ''));
}
return this.sendHttpRequest<Type>(method, request);
})
);
return this.sendHttpRequest<Type>(method, request);
}
private getRequest(request: RequestData | string | null): RequestData {
if (request === null)
return this.createRequestBuilder().build;
if (typeof request === 'string')
return this.createRequestBuilder().setEndpoint(request as string).build;
return request as RequestData;
}
public createRequestBuilder() {
this.request = RequestBuilder.getStandardRequestData();
return new RequestBuilder(this);
return new RequestBuilder();
}
public get<Type>(endpoint: string = ''): Observable<Type> {
if (endpoint)
this.request.endpoint = endpoint;
return this.makeHttpRequest<Type>('get');
public get<Type>(request: RequestData | string | null = null): Observable<Type> {
return this.makeHttpRequest<Type>('get', this.getRequest(request));
}
public post<Type>(endpoint: string = ''): Observable<Type> {
if (endpoint)
this.request.endpoint = endpoint;
return this.makeHttpRequest<Type>('post');
public post<Type>(request: RequestData | string | null = null): Observable<Type> {
return this.makeHttpRequest<Type>('post', this.getRequest(request));
}
public put<Type>(endpoint: string = ''): Observable<Type> {
if (endpoint)
this.request.endpoint = endpoint;
return this.makeHttpRequest<Type>('put');
public put<Type>(request: RequestData | string | null = null): Observable<Type> {
return this.makeHttpRequest<Type>('put', this.getRequest(request));
}
public delete<Type>(endpoint: string = ''): Observable<Type> {
if (endpoint)
this.request.endpoint = endpoint;
return this.makeHttpRequest<Type>('delete');
public delete<Type>(request: RequestData | string | null = null): Observable<Type> {
return this.makeHttpRequest<Type>('delete', this.getRequest(request));
}
public addAuth() {
const token = localStorage.getItem(ApiService.tokenKey);
if (!token)
return this;
const authToken = AuthToken.httpHeader((JSON.parse(token) as AuthToken));
authToken.keys().forEach(key => this.request.httpHeaders = this.request.httpHeaders.append(key, authToken.get(key) ?? ''));
public addAuth(request: RequestData) {
request.needAuth = true;
return this;
}