diff --git a/frontend/src/app/backend.service.ts b/frontend/src/app/backend.service.ts index ce7a469..e6b7074 100644 --- a/frontend/src/app/backend.service.ts +++ b/frontend/src/app/backend.service.ts @@ -1,41 +1,33 @@ import { Injectable, NgModule } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable } from 'rxjs'; +import { mergeMap } from 'rxjs/operators'; -import { ConfigService } from './config.service'; +import { Config, ConfigService } from './config.service'; @Injectable({ providedIn: 'root' }) @NgModule() export class BackendService { - backendUrl = 'http://localhost:3001'; - constructor(private http: HttpClient, private configService: ConfigService) { - if (configService.config && configService.config.backendUrl) { - this.backendUrl = configService.config.backendUrl; - } - } + constructor(private http: HttpClient, private configService: ConfigService) {} getBlocks(page: number, perPage: number): Observable { - return this.http.get(`${this.backendUrl}/api/blocks`, { - params: new HttpParams({ - fromObject: { page: page.toString(), perPage: perPage.toString() } - }) - }); + return this.request('/api/blocks'); } searchBlock(query: string): Observable { - return this.http.get(`${this.backendUrl}/api/block/${query}`); + return this.request(`/api/block/${query}`); } getBlock(blockHash: string): Observable { - return this.http.get(`${this.backendUrl}/api/block/${blockHash}`); + return this.request(`/api/block/${blockHash}`); } getBlockByHeight(height: number): Observable { - return this.http.get(`${this.backendUrl}/api/block/height/${height}`); + return this.request(`/api/block/height/${height}`); } getRawBlock(blockHash: string): Observable { - return this.http.get(`${this.backendUrl}/api/block/${blockHash}/raw`); + return this.request(`/api/block/${blockHash}/raw`); } getBlockTransactions( @@ -43,70 +35,85 @@ export class BackendService { page: number, perPage: number ): Observable { - return this.http.get(`${this.backendUrl}/api/block/${blockHash}/txns`, { - params: new HttpParams({ + return this.request( + `/api/block/${blockHash}/txns`, + new HttpParams({ fromObject: { page: page.toString(), perPage: perPage.toString() } }) - }); + ); } getTransactions(page: number, perPage: number): Observable { - return this.http.get(`${this.backendUrl}/api/transactions`, { - params: new HttpParams({ + return this.request( + '/api/transactions', + new HttpParams({ fromObject: { page: page.toString(), perPage: perPage.toString() } }) - }); + ); } getTransaction(txId: string): Observable { - return this.http.get(`${this.backendUrl}/api/tx/${txId}`); + return this.request(`/api/tx/${txId}`); } getRawTransaction(txId: string): Observable { - return this.http.get(`${this.backendUrl}/api/tx/${txId}/rawData`); + return this.request(`/api/tx/${txId}/rawData`); } getAddressInfo(address: string, lastSeenTxid?: string): Observable { - return this.http.get(`${this.backendUrl}/api/address/${address}`, { - params: new HttpParams({ + return this.request( + `/api/address/${address}`, + new HttpParams({ fromObject: { lastSeenTxid: (lastSeenTxid || '').toString() } }) - }); + ); } searchTransaction(query: string): Observable { - return this.http.get(`${this.backendUrl}/api/tx/${query}/get`); + return this.request(`/api/tx/${query}/get`); } getColors(lastSeenColorId?: string): Observable { - return this.http.get(`${this.backendUrl}/api/colors`, { - params: new HttpParams({ + return this.request( + '/api/colors', + new HttpParams({ fromObject: { lastSeenColorId: (lastSeenColorId || '').toString() } }) - }); + ); } getColor(colorId: string, lastSeenTxid?: string): Observable { - return this.http.get(`${this.backendUrl}/api/color/${colorId}`, { - params: new HttpParams({ + return this.request( + `/api/color/${colorId}`, + new HttpParams({ fromObject: { lastSeenTxid: (lastSeenTxid || '').toString() } }) - }); + ); } validateOpenedValue(opened_value: string): Observable { - return this.http.get(`${this.backendUrl}/api/validate/${opened_value}`); + return this.request(`/api/validate/${opened_value}`); } checkMaterialTrackingTransaction(txId: string): Observable { - return this.http.get( - `${this.backendUrl}/api/check_material_tracking_balance/${txId}` + return this.request(`/api/check_material_tracking_balance/${txId}`); + } + + private request(url: string, params?: HttpParams): Observable { + return this.getConfig().pipe( + mergeMap((config: Config) => { + return this.http.get(`${config.backendUrl}/${url}`, { params }); + }) ); } + + private getConfig(): Observable { + return this.configService.getConfig(); + } } diff --git a/frontend/src/app/config.service.ts b/frontend/src/app/config.service.ts index 8734513..fa69b3f 100644 --- a/frontend/src/app/config.service.ts +++ b/frontend/src/app/config.service.ts @@ -1,9 +1,9 @@ import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; -import { catchError, retry } from 'rxjs/operators'; +import { catchError, mergeMap, retry } from 'rxjs/operators'; /*** * Config service to supply configuration items from assets/config.json file. @@ -21,6 +21,7 @@ export interface Config { export class ConfigService { configUrl = 'assets/config.json'; config: Config; + observable: Observable; constructor(private http: HttpClient) {} @@ -34,6 +35,21 @@ export class ConfigService { } getConfig(): Observable { + if (this.config) { + return new Observable(observer => { + observer.next(this.config); + observer.complete(); + }); + } + + if (this.observable) { + return this.observable; + } + + return (this.observable = this.loadConfig()); + } + + private loadConfig(): Observable { return this.http.get(this.configUrl).pipe( retry(3), // retry a failed request up to 3 times catchError(this.handleError) // then handle the error